Vim mode in Obsidian: setup, vimrc and limits
Turn on Settings › Editor › Advanced › Vim key bindings ("Use Vim key bindings when editing") and Obsidian's editor gets Normal, Insert and Visual modes. It is CodeMirror's Vim emulation, so motions, operators, text objects, macros and :s work, but mappings don't survive a restart. For that, install the community plugin Vimrc Support and put your settings in .obsidian.vimrc in the vault root.
| Feature | Built in | With Vimrc Support |
|---|---|---|
| Motions, operators, text objects | Yes | Yes |
| Visual mode: character, line, block | Yes | Yes |
| Macros (q, @), marks, jump list | Yes | Yes |
Search (/, *, #) and :s, :g, :sort | Yes | Yes |
| Mappings that persist | No: lost on restart | Yes, from .obsidian.vimrc |
| Yank to the system clipboard | Not by default | set clipboard=unnamed |
| Run Obsidian commands from Vim | No | obcommand, via exmap |
| Jump between headings and links | No | [[ ]] for headings, gl gL for links |
Turn on Vim key bindings
- Open Settings, choose Editor, scroll to Advanced, and switch on Vim key bindings.
- Press i to type and Esc to return to Normal mode, as in Vim.
There is nothing else to install for the basics. Mappings that last, the system clipboard and the extras below come from a plugin.
What works: CodeMirror's Vim mode
Obsidian's Vim mode is, in the words of the Vimrc Support plugin's author, mostly the codemirror-vim extension for CodeMirror. That project lists, among its features:
- All the common motions and operators, including text objects (ciw, da(, ci", dap).
- Visual mode in all three flavours: character (v), line (V) and block (Ctrl-v).
- Full macro support with q and @.
- Marks with ` and ', and the jump list with Ctrl-o and Ctrl-i.
- Incremental, highlighted search with /, ?, *, #, g* and g#, with history.
:sand:%s, including the confirm flag, plus:sort,:global, and:map,:nmapand:vmap.
The same project says plainly that it "does not strive to become a complete vim implementation", so expect gaps in the less common corners. A good habit: try a command at the : prompt in Obsidian before relying on it.
Warm up: text objects in a note
Text objects are in CodeMirror's Vim mode, so these work in an Obsidian note. Change the word in quotes with ci", then delete the out-of-date paragraph, and the blank line after it, with dap.
This editor needs a keyboard. Read on, and play it at your computer.
Keep your settings: Vimrc Support and .obsidian.vimrc
Anything you :map by hand is gone when Obsidian restarts. The community plugin Vimrc Support (by esm7) fixes that by reading a file of Vim commands when a vault opens.
- Install it from Settings › Community plugins (turn community plugins on first), and keep Obsidian's Vim key bindings switched on: the plugin adds to them, it doesn't replace them.
- Create a file named
.obsidian.vimrcin the vault root, not inside the.obsidianfolder. Each vault needs its own copy.
A useful start, taken from the plugin's own example:
nmap j gjandnmap k gk: move by screen line, which matters in notes full of wrapped paragraphs.nmap H ^andnmap L $: start and end of line.nmap <F9> :nohl<CR>: clear search highlighting.set clipboard=unnamed: yank to the system clipboard.
For j k to leave Insert mode, try :imap jk <Esc> at the : prompt first; the plugin's author recommends testing every command interactively before adding it to the file, because commands that fail in the file fail silently.
The keys behind those mappings
The mappings above lean on plain Vim keys. Type each from memory.
Run Obsidian commands from Vim keys
Vimrc Support adds obcommand, which runs any Obsidian command by its ID. Type :obcommand with no arguments and the full list of IDs appears in the developer console (Ctrl+Shift+I).
Because of a CodeMirror bug, mapping straight to a command with an argument doesn't work, so name it first with exmap, then map the name:
exmap back obcommand app:go-backnmap <C-o> :back<CR>exmap forward obcommand app:go-forwardnmap <C-i> :forward<CR>
Note the colon: exmap names have none, the nmap needs one. You may also need to remove Obsidian's own hotkey for a key before your mapping wins.
The plugin has a few more extras: surround to wrap a word or selection in text of your choice (handy for making a wikilink), pasteinto to paste the clipboard into the selected text or word (useful for making links), and ready-made motions: [[ and ]] for the previous and next heading, gl and gL for links, gf to open the link under the cursor, and zk and zj to move while skipping folds.
Gaps and gotchas
- No real Vim underneath. Plugins, Vim script and most options from a real
.vimrcdon't apply; the file only understands what CodeMirror's Vim mode and the plugin support. - Ex mappings need `<CR>`. Since Obsidian 1.7.2, a Normal mode mapping to an Ex command must end in
<CR>, as in real Vim:nmap <F9> :nohl<CR>, notnmap <F9> :nohl. - Silent failures. A line in
.obsidian.vimrcthat doesn't work produces no error. - `obcommand` isn't an official API, so a future Obsidian update could break mappings built on it.
- JavaScript commands (
jscommand,jsfile) are off by default, and the plugin warns about the security risk of turning them on. - Maintenance. The plugin's author is looking for a new maintainer and only handles urgent fixes, so check its page before depending on it heavily.
The motions are the same as in Vim, and the course teaches them in a real editor in the browser.
Questions
- Where is the Vim setting in Obsidian?
- Settings › Editor › Advanced › Vim key bindings. Switch it on to edit with Vim keys.
- Where does .obsidian.vimrc go?
- In the root folder of your vault, next to your notes, not inside the hidden
.obsidianfolder. It needs the Vimrc Support community plugin to be read. - How do I copy to the system clipboard in Obsidian Vim mode?
- Install Vimrc Support and add
set clipboard=unnamedto.obsidian.vimrc. Then y copies to the system clipboard.