No description
Find a file
2026-07-22 00:30:02 +02:00
.github chore: cli-friendly issue template 2026-07-16 15:26:34 +02:00
docs chore: bumped version 2026-07-22 00:30:02 +02:00
src refactor: settings pages 2026-07-22 00:24:07 +02:00
test feat: smear cursor and animated cursor 2026-07-21 20:41:14 +02:00
test-vault feat: gutter linenumbers 2026-07-12 21:12:09 +02:00
.editorconfig Initial release 2026-06-13 01:49:22 +02:00
.gitignore chore: bumped version 2026-07-04 03:23:10 +02:00
.npmrc Initial commit 2026-06-12 13:13:52 +02:00
.prettierignore chore: prettier 2026-06-25 13:09:36 +02:00
ACKNOWLEDGEMENTS.md chore: removed nucleo-matcher-wasm 2026-07-09 04:19:53 +02:00
AGENTS.md refactor: settings pages 2026-07-22 00:24:07 +02:00
CHANGELOG.md chore: bumped version 2026-07-22 00:30:02 +02:00
CONTRIBUTING.md feat: paged settings 2026-07-21 22:45:37 +02:00
esbuild.config.mjs feat: snippet system infrastructure 2026-07-13 13:51:38 +02:00
eslint.config.mts feat: undotree support 2026-07-20 00:49:24 +02:00
flake.lock Initial release 2026-06-13 01:49:22 +02:00
flake.nix Initial release 2026-06-13 01:49:22 +02:00
justfile chore: test mocks 2026-07-14 17:10:29 +02:00
KNOWN_LIMITATIONS.md refactor: settings pages 2026-07-22 00:24:07 +02:00
LICENSE Initial release 2026-06-13 01:49:22 +02:00
manifest.json chore: bumped version 2026-07-22 00:30:02 +02:00
NEOVIM_PLUGIN_ECOSYSTEM_ANALYSIS.md docs: analysis of neovim plugin ecosystem results 2026-07-07 14:50:21 +02:00
package-lock.json chore: bumped version 2026-07-22 00:30:02 +02:00
package.json chore: bumped version 2026-07-22 00:30:02 +02:00
quartz.config.yaml chore: bumped version 2026-07-03 19:35:23 +02:00
README.md feat: smear cursor and animated cursor 2026-07-21 20:41:14 +02:00
styles.css refactor: settings pages 2026-07-22 00:24:07 +02:00
tsconfig.json Initial release 2026-06-13 01:49:22 +02:00
version-bump.mjs chore: improve version bump 2026-07-11 15:19:21 +02:00
versions.json chore: bumped version 2026-07-22 00:30:02 +02:00
vitest.config.ts feat: async lua and pcall support 2026-07-17 18:57:10 +02:00
wdio.conf.mts feat: pickers for omnisearch, dataview, tasks 2026-07-12 19:23:05 +02:00

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.

Full documentation →

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.lua with conditional logic, function keymaps, 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.uv timers, autocommands (19 events), vim.obsidian namespace (including vim.obsidian.im for input method control), buffer-local keymaps, async file reading (vim.ob.fs.read), multi-file configs via require(), collectgarbage() support, __gc userdata finalization, and Neovim-compatible syntax
  • Built-in vimrc.obsidian.vimrc loader with 75+ configurable settings and which-key support with Lucide icons
  • Flash motions — enhanced f/F/t/T with labels on all visible matches (flash.nvim-inspired). Auto-jumps on single match. Operator-pending (df, cf, yf), visual mode, multi-line search. Incremental s jump 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/csf for function calls, dot-repeat for ys with text objects)
  • Hard-wrap formatting — Markdown-aware gq/gw operators with prefix preservation
  • Replace-with-registergr{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 exploreroil.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 statuscolumn API 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 (AZ), 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-editor state with session persistence, composition guard, :IMToggle/:IMStatus ex 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 on gd, picker selection, harpoon, oil, EasyMotion, and 100+ other navigation paths. Persists across sessions. :jumps displays the list. set jumplist/set jumplistsize for configuration
  • Undo treeundotree-style branching undo history visualization. g-/g+ navigate chronologically across all branches with buffer content restoration. :earlier/:later by count, time, or save point. :undolist modal. 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-motion support. Disabled by default. 8 settings: animatedCursor, smoothCursor, cursorSmoothness, smearTrail, smearStiffness, smearTrailingStiffness, smearDamping, smearMaxLength
  • Subword motions — spider.nvim-style w/b/e/ge override 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

  1. Download main.js, manifest.json, and styles.css from the latest release.
  2. Create a folder vim-motions in <your-vault>/.obsidian/plugins/.
  3. Copy the downloaded files into that folder.
  4. Restart Obsidian and enable the plugin in Settings → Community plugins.

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

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