Fixed
- Which-key descriptions not showing for keymaps set via Lua —
vim.keymap.setandvim.obsidian.leader.setwith adescoption showed raw action names (lua-action-0), command strings (:Oil<CR>), or internal function names (harpoonSelect1) instead of the user's description. The codemirror-vim fork normalizes literal space characters to<Space>notation in key strings (e.g.," ff"→"<Space>ff"), but the which-key overlay stored and looked up label keys using unnormalized literal spaces — all lookups missed. Additionally, the leader-only which-key mode never triggered with space as leader because thevim-keypressevent emits"<Space>"but the overlay compared against the raw" "character. (#58)- Plugin:
src/ui/which-key.ts(normalizeVimKey()function mirroring the fork'snormalizeKeyString,normalizedLeaderKeyfield for key event comparison, normalized lookups inshowLeaderBindings/showCompletions/onKeyPressLeaderOnly),src/main.ts(rebuildWhichKey()normalizes allcommandLabelsandgroupLabelsmap keys from settings, vimrc, and Lua sources)
- Plugin:
vim.opt.clipboardsilently ignored in init.lua — settingvim.opt.clipboard = "unnamed"or"unnamedplus"in init.lua had no effect. The Luavim.opthandler only routed options through theKNOWN_SET_OPTIONStable, butclipboardwas special-cased in the vimrc loader and missing from that table. Yanks never synced to the system clipboard when configured via Lua. Same issue affectedvim.opt.textwidth. (#56)- Plugin:
src/vimrc/loader.ts(SideEffectOpttype,clipboard/textwidth/guicursoradded toKNOWN_SET_OPTIONS),src/lua/api.ts(special-case blocks removed, unifiedKNOWN_SET_OPTIONSpath),src/main.ts(initial settings load from saved values),src/lua/loader.ts(setOptioncallback)
- Plugin:
- Settings-based clipboard and textwidth not restored on plugin restart — if a user set clipboard or textwidth via the Settings UI, the value was saved to disk but not re-applied to the vim engine on the next Obsidian startup. The saved
this.settings.clipboardandthis.settings.textwidthwere never pushed tovim.setOption()during plugin load. Fixed by applying saved side-effect options afterregisterVimOptions().- Plugin:
src/main.ts(initial settings loop usingKNOWN_SET_OPTIONSsideEffects)
- Plugin:
Changed
- Vim option architecture:
SideEffectOpttype — options that require side effects beyondthis.settings[key] = value(clipboard, textwidth, guicursor) are now declared in theKNOWN_SET_OPTIONStable with asideEffecttype and anapply()callback. Previously, these options were special-cased with separateifblocks in both the vimrc loader and the Luavim.opthandler — adding a new side-effect option required touching 2-3 files manually, and missing one path caused silent failures. Now there is a single declaration point. The vimrc loader, Lua handler, and initial settings load all route through the same table-driven path.- Plugin:
src/vimrc/loader.ts(SideEffectOptinterface,applyKnownSetOptionsideEffect handling, special-case blocks removed),src/lua/api.ts(unifiedKNOWN_SET_OPTIONSpath)
- Plugin:
Added
- Snippets — VS Code-compatible snippet expansion with tabstop navigation, linked mirrors, variable resolution ($CURRENT_YEAR, $TM_FILENAME, $UUID, etc.), and context-aware filtering (prose/code/frontmatter). Ships 40+ Obsidian-adapted snippets (headings, callouts, wikilinks, tables, frontmatter, math, date/time). Three trigger mechanisms: CM6 completion menu, Tab expansion (vim-native), and ex commands (
:snippet name,:snippetspicker). Bundled snippets toggleable via settings. - User snippet directory — load custom VS Code JSON snippet files from a configurable directory. Supports vault-relative and absolute paths (with
~expansion, desktop only). User snippets override bundled snippets on prefix collision. - Snippet Lua DSL — LuaSnip-inspired
vim.snippet.*API:s(),t(),i(),c(),rep(),fmt()for static snippets that compile to VS Code JSON at load time.f()(function nodes),d()(dynamic nodes),sn()(snippet nodes),r()(restore nodes) for reactive snippets that execute Lua functions via fengari at edit time. - Snippet context filtering — snippets can be restricted to specific editing contexts (
"prose","code:js","code:*","frontmatter") via a"context"field in JSON or thecontextoption in Lua DSL. - Choice node cycling —
Ctrl+N/Ctrl+Pcycle through choice options (${1|a,b,c|}) on active snippet fields. - Snippet picker —
:snippetsopens the telescope-style fuzzy finder with snippet preview.:snippet nameexpands by name. @codemirror/autocompletefork — recursive descent snippet parser replacing CM6's regex parser, supporting choice nodes, nested placeholders, transforms (parsed, not applied), and bare$1syntax. Fork at saberzero1/autocomplete.- 4 new settings: Enable snippets, Bundled snippets, Snippet directory, Trigger mode
- 4 new vimrc
setoptions:snippets,snippetbundled,snippetdir,snippettrigger - 13 new
vim.snippet.*Lua API functions - Plugin files:
src/snippets/(14 files),src/lua/snippet-api.ts,src/snippets/dynamic-bridge.ts - Fork files:
~/Repos/autocomplete/src/snippet.ts(parser),~/Repos/autocomplete/src/index.ts(exports)
Tests
- 9 unit tests in
test/unit/which-key.test.ts:normalizeVimKey()— space conversion, idempotence, angle-bracket preservation, mixed notation - 4 e2e regression tests in
test/specs/lua-space-leader.e2e.ts: which-key descriptions with space leader — string command desc, function callback desc,allmode desc,vim.obsidian.leader.setdesc - 11 new e2e tests in
test/specs/lua-config.e2e.ts:vim.opt.clipboard = "unnamed"applies from init.lua (1 test)yy/yw/ddpopulate+register when clipboard set via Lua (3 tests)vim.opt.textwidthandvim.opt.twalias from init.lua (2 tests)- Dual-config override precedence: Lua overrides vimrc for clipboard, textwidth, scrolloff (3 tests)
- Error resilience: unknown Lua option preserves vimrc clipboard; invalid textwidth (
-5) preserves vimrc value (2 tests)
- 7 e2e spec files (22 passing, 5 skipped) covering expansion, tabstops, variables, context, f()/d() nodes, static regression
- 15 LuaSnip golden comparison unit tests (extracted from LuaSnip test suite commit
0abc8f3) - 359 total unit tests passing
Documentation
docs/features/snippets.md(new feature page)docs/features/index.md,docs/reference/keybindings.md,docs/configuration/settings.md,docs/features/ex-commands.md,docs/configuration/vimrc.md,docs/configuration/lua-config.md(updated)AGENTS.md(fork dependency + page ownership)KNOWN_LIMITATIONS.md(7 limitation entries)
Full Changelog: 0.52.0...0.53.0