mvim

A menu-bar app for macOS 14 or later

Vim's modal editing in the text fields of your Mac.

mvim reads and edits the focused field through Accessibility, and takes the keys it needs with a keyboard event tap. Type as usual, and press Esc for Normal mode.

No release yet · Free software under the GNU GPL

In native Mac apps

In most native Mac apps mvim can read and write the field and set its selection, so Normal mode also draws a block cursor. Choose a use case to watch it.

Each step is what mvim's engine does with these keys, in its simulation of a native Mac text field.

What works

A subset of Vim, in fields mvim can read and write. The README's What works lists more.

Move
h j k l w b e 0 ^ gg G f t
Edit
x r J ~ p P ., and u ⌃R with the app's own undo
Operators
d c y with most motions, iw or aw, and dd cc yy
Insert
i a I A o O
Visual
v, then d c y, though a selection can end one character short
Search
/ or ?, then n N

Counts, marks and registers work too. : commands, macros, z commands and text objects other than words beep instead.

In Chrome and Electron apps

Chromium browsers and Electron apps, such as Chrome, Dia and Linear, let mvim read a field but not set its selection. There mvim runs the same Normal-mode commands by pressing keys, and checks the field after each step: when the field does not answer as planned, it beeps and stops rather than edit the wrong text.

A simulation, not a recording: mvim's engine runs these keys in simulated fields modeled on Chromium's and Notion's.

It learns

When one of a field's writes, or one of the app's keys mvim relies on, fails its check, mvim switches that capability off for fields like that one until the app updates. The menu lists what it learned, with the day it failed; Try Again forgets it, and On and Off override it.

Blocks stay one session

Notion comes with its own defaults, since each of its blocks is a separate field. Moving between the blocks of one document keeps the mode you were in.

What changes there

There is no block cursor, and o and O paste their new line, because ⏎ could send a message.

Built around the Mac

Esc switches modes

Choose it under Normal Mode Key in the menu. In Normal mode with nothing half-typed, Esc still goes to the app, so press it twice to close a dialog. The default, ⌃[ (Control and the key to the right of P), keeps working either way.

The mode is in your menu bar

An outlined i or r while keys type, a filled n or v while they are commands. Where mvim can set the selection, Normal mode also draws a block cursor.

Your shortcuts stay yours

In Insert mode mvim takes only Esc and ⌃[. In Normal mode apps keep every ⌘ and ⌥ combination and most ⌃ ones, so ⌃A, ⌃E and ⌃K work as in any Mac text field, and a key mvim does not know beeps instead of typing.

One switch per app

Auto works in text fields, text areas and combo boxes, never in password fields. Terminals and code editors start Off. Force drives apps that expose no text field to Accessibility, with arrow keys and ⌘Z, ⌘X, ⌘C and ⌘V.

Install

There is no release yet, so build mvim from source. You need Xcode (the full app, not only its command-line tools), XcodeGen and an Apple Development signing certificate.

  1. Clone the repository and set DEVELOPMENT_TEAM in project.yml to your team ID, so macOS keeps mvim's permissions across builds.
  2. Run make release and copy .release/mvim.app to /Applications.
  3. Allow Input Monitoring when macOS asks. Then choose Accessibility: not granted in mvim's menu and switch mvim on there.
  4. Quit mvim and open it again: it creates its keyboard tap only at launch.
  5. Choose Esc under Normal Mode Key in mvim's menu.

Step-by-step instructions

Privacy

mvim needs two permissions: Accessibility, to read and edit the focused field and to post keys, and Input Monitoring, for its keyboard tap. The tap sees every key you press, but mvim acts only on keys typed into a field it is working in, and it stands aside while macOS has Secure Event Input on, as it does in a password field.

What mvim keeps and logs