A polished, Neovim-native experience inside Obsidian. Vim Motions adds what’s missing from Obsidian’s built-in Vim mode: Markdown-aware text objects, structural navigation, hard-wrap formatting, workspace keyboard control, EasyMotion, a telescope-style fuzzy picker, Lua configuration with vim.keymap.set / vim.opt / vim.fn / vim.api / vim.ob / vim.tbl_* / autocommands / timers / highlight groups / global keymaps / which-key labels, and a built-in .obsidian.vimrc loader.
Feature highlights
- Markdown text objects — operate on bold, italic, code, math, links, blockquotes, code blocks, tables, and more with standard Vim operators
- Structural navigation — jump between headings, lists, links, and buffers with
]h,]l,]n,]b - Lua configuration —
.obsidian.init.luawithvim.keymap.set,vim.opt(includingguicursor),vim.fn(includingundotree()),vim.api(buffer APIs,nvim_set_hl),vim.ob(68 Obsidian-specific functions: metadata, filesystem, UI, cursor, surround, leader),vim.tbl_*,vim.json,vim.inspect,vim.regex(ECMAScript RegExp),vim.schedule/vim.uvtimers, 19 autocommand events, buffer-local keymaps,vim.obsidian.keymap(global keymaps),vim.obsidian.whichkey(which-key labels), async file reading (vim.ob.fs.read), multi-file configs viarequire(), fuzzy picker API, and hot-reload on save - Built-in vimrc —
.obsidian.vimrcloader with 75+ configurable settings and hot-reload on save - Flash motions — enhanced
f/F/t/Twith jump labels, incrementalssearch, post-commit//?labels, clever-f - EasyMotion / Hop — jump to any visible position with two keystrokes
- Workspace keyboard control — navigate panes, tabs, and sidebar without a mouse
- Surround — add, change, or delete surrounding delimiters (nvim-surround parity, custom pairs)
- Hard-wrap formatting — Markdown-aware
gq/gwoperators - 100+ ex commands —
:sp,:vs,:e,:grep,:ob, fuzzy picker commands, and more - Vimium-style hints — navigate the entire Obsidian UI with keyboard hints
- Undo tree — branching undo history visualization with
g-/g+chronological navigation,:earlier/:latertime travel, sidebar tree view, and optional persistence
Get started
New to Vim Motions?
Start with installation to install the plugin, then follow recommended-setup to configure Obsidian for the best experience.
Quick links
- Keybinding cheat sheet — complete reference for all motions, text objects, operators, and commands
- Settings reference — all 100 configurable items with defaults and vimrc equivalents
- Known limitations — architectural constraints and workarounds
What’s new in 0.149.0
- Non-Markdown picker previews are configurable —
pickerNonMarkdownPreview(set pickerpreview,vim.opt.pickerpreview) choosesrendered(default),hidden, orraw.renderedembeds images,svgandcanvasnatively and shows a name/type/size card for PDFs, video and audio. Markdown is always previewed, and the setting applies live without a reload (settings reference, #172) - The picker no longer reads binary files to preview them — scrolling past a multi-megabyte PDF used to decode the whole binary as UTF-8, and Obsidian cached that string, so memory grew with every binary encountered. Size is now checked from file metadata before any read, in every mode
- Preview rendering is debounced — holding
jissued a fresh read and render per keystroke (roughly 30 previews a second). A 100 ms leading-plus-trailing debounce keeps isolated keypresses instant while collapsing a burst to two - The preview pane no longer leaks
Componentinstances — raw-string, empty, loading and error transitions all replaced pane content while leaving embeds, images and transclusions registered. A single teardown path now runs on every transition, including close - Sturdier preview error handling — a synchronous throw from a picker source’s
preview()is caught as the provider API documents, and superseded in-flight previews are rejected by generation instead of item id, so re-selecting the same item can no longer render a stale result
See the full changelog for details.