Vim Motions
approvedby Emile Bangma
Full Neovim experience inside Obsidian with Lua scripting, Flash/EasyMotion jumps, Telescope-style picker, Oil explorer, snippets, surround, animated cursor, undo tree, and Markdown text objects. - This plugin has not been manually reviewed by Obsidian staff.
Vim Motions
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, Lua configuration with vim.keymap.set / vim.opt / vim.fn / vim.api / vim.tbl_* / autocommands / timers / highlight groups, and a built-in .obsidian.vimrc loader.
Features
- Markdown text objects — operate on bold, italic, code, math, links, blockquotes, code blocks, callouts, tags, table cells, subwords, numbers, quotes, wikilinks, URLs, arguments, and indentation with
d,c,y,v - Structural navigation — jump between headings, lists, links, and buffers with
]h,]l,]n,]b - Lua configuration —
.obsidian.init.luawith conditional logic, function keymaps,vim.vpredefined variables (count,count1,register,operator,searchforward, constants),{ expr = true }expression mappings,vim.fn.*,vim.api.*(buffer APIs,nvim_set_hl),vim.tbl_*,vim.snippet.*,vim.json,vim.inspect,vim.regex(ECMAScript RegExp),vim.schedule/vim.defer_fn/vim.uvtimers, autocommands (19 events, mode events fire per-view across all editors),vim.obsidiannamespace (includingvim.obsidian.imfor input method control), buffer-local keymaps, async file reading (vim.ob.fs.read), multi-file configs viarequire(),collectgarbage()support,__gcuserdata finalization, and Neovim-compatible syntax - Built-in vimrc —
.obsidian.vimrcloader with 75+ configurable settings and which-key support with Lucide icons - Flash motions — enhanced
f/F/t/Twith labels on all visible matches (flash.nvim-inspired). Auto-jumps on single match. Operator-pending (df,cf,yf), visual mode, multi-line search. Incrementalsjump mode (type multiple chars to narrow, labels update live), post-commit//?search labels, clever-f repetition, label conflict skipping,[3/15]search match counter. Dynamically sized match highlights and labels positioned after matched text (flash.nvim parity) - EasyMotion / Hop — jump to any visible position with two keystrokes, with operator-pending support
- Workspace keyboard control — navigate panes, tabs, and sidebar without a mouse (
<C-w>,gt/gT,:sp/:vs) - Surround — add, change, or delete surrounding delimiters (vim-surround with Markdown support, including
dsf/csffor function calls, dot-repeat foryswith text objects, insert-mode<C-G>swith both delimiters inserted up front) - Hard-wrap formatting — Markdown-aware
gq/gwoperators with prefix preservation - Replace-with-register —
gr{motion}replaces text with register contents without clobbering the register (vim-ReplaceWithRegister parity) - Yank-ring paste cycling — cycle through numbered register history with
<C-p>/<C-n>after pasting. Wraps around registers"1–"9. Cancels on any non-cycling command. - Table editing — cell navigation, text objects, manipulation commands, format-on-exit auto-alignment, cursor-aware table widget, and embedded per-cell editing with vim-enabled cell editors and direct table manipulation (
o,dd,J/K,H/L,=) - Oil explorer — oil.nvim-inspired file manager: edit directories as buffers, create/rename/delete files with vim commands
- Telescope-style picker — fuzzy finder with 14 built-in sources (files, buffers, commands, headings, outline, grep, live grep, marks, registers, tags, backlinks, recent, harpoon, snippets), preview pane, frecency scoring, bundled integrations for Omnisearch, Obsidian Tasks, and Dataview, and a provider API for external plugin integration
- Snippets — VS Code-compatible snippet expansion with tabstop navigation, variables, choice nodes, context filtering. 60+ bundled Obsidian snippets. User-defined snippets via JSON files or LuaSnip-inspired Lua DSL with reactive
f()/d()nodes - 100+ ex commands —
:sp,:vs,:e,:grep,:ob,:Oil,:sidebar, navigation/action aliases, and more - Vimium-style hints — navigate the entire Obsidian UI with keyboard hints (
f,F,yf,df) - Line numbers — configurable line number gutter with absolute, relative, and hybrid modes. Neovim-compatible
statuscolumnAPI for custom gutter layouts (vim.opt.statuscolumn = "%s %l %r %C"). Cursor line highlight (cursorline/cursorlineopt), configurable number width, mobile-responsive gutter, and Obsidian's native line numbers suppressed when active - Marks — dedicated sign column gutter showing mark letters next to marked lines, configurable via
signcolumn(auto/always/off), consistent font size regardless of content, gutter layout matching Neovim (sign column → line numbers → fold column), global mark persistence across files and sessions (A–Z), and a grouped marks picker with cross-file navigation - Harpoon — pin files to numbered slots for instant switching (
<leader>1–<leader>9), cursor position tracking, persistence across sessions, auto-updating on file rename/delete - Fully remappable keybindings — every keybinding can be customized via Lua or vimrc across all contexts (editor, oil explorer, picker, workspace)
- Folding — full Neovim-style fold commands:
zf(create),zd(delete),zE(eliminate all),zm/zr(incremental level), custom fold providers for frontmatter and callouts, descriptive fold placeholder text, fold-aware navigation (auto-unfold on]h), cross-session fold persistence, and optional fold column gutter (set foldcolumn) with click-to-fold - Input method switching — automatic IM switching for CJK users when entering/leaving insert mode. Supports macism, im-select, fcitx5-remote, ibus, and any external binary. Platform presets for one-click setup, per-view state across all editors (split panes, popovers, canvas cards) with session persistence, composition guard,
:IMToggle/:IMStatusex commands, Lua API (vim.obsidian.im). Desktop only. - Vim in text areas — focused
<textarea>elements in modals and plugin UIs are replaced with a vim-enabled editor overlay. Starts in insert mode for transparent typing; press Escape for normal mode, second Escape returns to modal. Experimental, disabled by default. Desktop only. - Cross-note jump list —
<C-o>and<C-i>navigate backward/forward through jump history across notes. Jumps recorded ongd, picker selection, harpoon, oil, EasyMotion, and 100+ other navigation paths. Persists across sessions.:jumpsdisplays the list.set jumplist/set jumplistsizefor configuration - Undo tree — undotree-style branching undo history visualization.
g-/g+navigate chronologically across all branches with buffer content restoration.:earlier/:laterby count, time, or save point.:undolistmodal. Sidebar view (:UndoTreeToggle) with tree rendering, keyboard nav, collapse/expand, diff preview.vim.fn.undotree()Lua API. Optional persistence (set undofile). 5 settings:enableUndoTree,undoTreeMaxNodes,undoTreePosition,undoTreeAutoOpen,undoFile - Animated cursor — canvas-based smooth cursor movement and smear-cursor.nvim-style spring-damper smear trail. Per-mode cursor shapes, configurable stiffness/damping/smoothness,
prefers-reduced-motionsupport, cross-platform resilience (heartbeat safety net, error recovery, visibility-change wakeup, fractional DPI rounding), and full vimrc/Lua configuration (set smoothcursor/vim.opt.smoothcursor). Disabled by default. 8 settings:animatedCursor,smoothCursor,cursorSmoothness,smearTrail,smearStiffness,smearTrailingStiffness,smearDamping,smearMaxLength - Subword motions — spider.nvim-style
w/b/e/geoverride stopping at camelCase, snake_case, and kebab-case boundaries. Opt-in setting. - Enhanced increment/decrement — dial.nvim-style
<C-a>/<C-x>cycling hex colors, booleans, dates, CSS values, and checkboxes - Custom text objects — define delimiter-pair text objects from Lua via
vim.textobject.add()+vim.gen_spec.pair() - External grep — optional ripgrep or GNU grep binary for native-speed vault search in the picker. Desktop only with in-memory fallback.
- Quality of life: Neovim defaults (
Y/Q), yank highlight, smart list continuation, scrolloff, insert escape sequences, chord display, powerline status bar, and settings hot-reload
Installation
From community directory
Search for "Vim Motions" in Settings → Community plugins → Browse.
Manual installation
- Download
main.js,manifest.json, andstyles.cssfrom the latest release. - Create a folder
vim-motionsin<your-vault>/.obsidian/plugins/. - Copy the downloaded files into that folder.
- Restart Obsidian and enable the plugin in Settings → Community plugins.
Recommended setup
Disable Obsidian's built-in Vim mode (Settings → Editor → Vim key bindings → off). Vim Motions provides its own enhanced vim engine — a fork of codemirror-vim — with Neovim-correct behavior, async motion support, correct cursor positioning in Live Preview, and theme-aligned styling.
The plugin also works with built-in vim mode enabled, but the fork provides a more accurate Vim experience. See the recommended setup guide for details.
Documentation
Full documentation: https://saberzero1.github.io/motions
- Getting started
- Features
- Lua configuration
- Settings reference
- Keybinding cheat sheet
- Remapping guide
- Known limitations
- Changelog
Requirements
- Obsidian v1.7.2 or later
- Desktop or mobile (physical keyboard recommended on mobile)
Development
npm install # Install dependencies
npm run dev # Development build (watch mode)
npm run build # Production build
npm run lint # Lint
npm run test:e2e # E2E tests (requires nix develop)
See CONTRIBUTING.md for the full development guide, testing strategy, and contribution guidelines.
License
MIT — Emile Bangma
For plugin developers
Search results and similarity scores are powered by semantic analysis of your plugin's README. If your plugin isn't appearing for searches you'd expect, try updating your README to clearly describe your plugin's purpose, features, and use cases.