212b300fb4
Clean, fully-wired parity fixes (skipping the accept-but-ignore ones):
- <D-CR> (macOS Cmd+Return) → follow_link_drop, alongside <C-S-CR>, in both
clients. Upstream binds both to VimwikiTabDropLink.
- plugin/nuwiki.vim global map block: fix the same diary collision the
buffer-local maps had — <Leader>w<Leader>t now opens today in a new tab and
<Leader>w<Leader>m (tomorrow) is added.
- Neovim TabIndex: add -count to NuwikiTabIndex and switch both
Vimwiki/NuwikiTabIndex from vim.v.count (always 0 in command context) to
<count>, so a count is actually honored.
- Converge VimwikiTableMoveColumn{Left,Right}: the Vim-branch commands now call
the table_move_column_left/right aliases, matching the Neovim branch.
- VimwikiColorize/NuwikiColorize: -nargs=1 → -nargs=* (all four defs) for
upstream parity; a bare :VimwikiColorize now prompts for the colour.
Docs (README + doc/nuwiki.txt) updated; mapping surfaces gain <D-CR> and
<Leader>w<Leader>m in both harnesses. vim 265+18, nvim 272, all green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
17 KiB
17 KiB
vimwiki → nuwiki Parity Gaps
Tracking document for closing the gap between nuwiki and the original vimwiki plugin across configuration, commands, and key mappings.
Source of truth for upstream: vimwiki master —
autoload/vimwiki/vars.vim (option defaults), plugin/vimwiki.vim +
ftplugin/vimwiki.vim (commands/mappings), doc/vimwiki.txt (prose).
Audited 2026-05-31. Check items off as they land. Each row cites the nuwiki fix site.
P1 — Core workflow gaps (fix first)
- Vim client split/tab link-follow commands —
VimwikiSplitLink,VimwikiVSplitLink,VimwikiGoBackLink,VimwikiTabnewLink,VimwikiTabDropLinkexist only in the Neovim branch. Vim users lose split-window link following and back-navigation. Fix:ftplugin/vimwiki.vim(Vim branch) — commands added +:Nuwiki*aliases;follow_link_drop()helper inautoload/nuwiki/commands.vim; true:tab droptab-reuse wired in both clients (lua/nuwiki/commands.luaopen_uri'tabdrop'case);<C-S-CR>repointed to tab-drop. gl<symbol>change-symbol mappings — upstream's one-key bullet/number symbol change (gl*gl#gl-gl1glagli… plusgL…) has no nuwiki keymap; only:…ChangeSymbol*commands exist. Fix: added normal-modegl{-,*,#,1,i,I,a,A}(item) +gL…(whole list) inlua/nuwiki/keymaps.lualists group andftplugin/vimwiki.vimVim-branch lists block, wired to the existinglist_change_symbol.1)stays command-only (upstream shadows it with1.); normal-mode only (server acts on cursor item / whole list, not a visual range).gl<Space>/gL<Space>semantics diverge — upstream = remove checkbox from item / list siblings; nuwiki rebound to remove done items. Same keys, different effect (parity trap). Fix: bound baregl/gLto remove-checkbox-item / -in-list for exact upstream parity (lua/nuwiki/keymaps.lualists block,ftplugin/vimwiki.vimVim-branch lists block); they share thegl…prefix so they fire aftertimeoutlen, just like upstream. Remove-done is now command-only::NuwikiRemoveDone(current list) gained a-bangso:NuwikiRemoveDone!reaches the whole-buffer sweep thatgL<Space>previously held (the only prior entry point). Normal-mode only.
Regressions (reported by users — verify, then fix)
<CR>link-follow: wrong window placement + no create-on-follow on the Vim clients — two related Vim-branch bugs (Neovim path was already correct): (a) on coc.nvim,<CR>opened the target in a new tab instead of the current window; (b) on both vim-lsp and coc,<CR>on a link to a not-yet-created page failed to open/create it. Root cause: the Vim follow path delegated to the LSP client's jump UI (:LspDefinition/CocActionAsync('jumpDefinition')). Those fetch the target's text before jumping — vim-lspreadfile()s it for the quickfix entry (autoload/lsp/utils/location.vim), which throwsE484for a missing file and aborts the jump (→ no create-on-follow); coc, lacking an explicit open command, fell back to the user'scoc.preferences.jumpCommand(→ new tab). The server itself was correct throughout — verified over JSON-RPC thattextDocument/definitionreturns a synthesised location for missing pages and resolves existing links. Fix: stop delegating.nuwiki#commands#follow_link_or_create()/follow_link_drop()now resolvetextDocument/definitiondirectly and open the URI ourselves via a shareds:open_definition(open_cmd)helper (autoload/nuwiki/commands.vim) —:editfor<CR>,tab dropfor<C-S-CR>.:editopens a buffer for a missing path (save creates it, matching vimwiki) and gives exact current-window placement regardless of the user's coc jumpCommand. Covered bycr.follow_opens_missing_page_in_current_windowindevelopment/tests/test-keymaps-vim.vim; manually reproducible viadevelopment/start-vim.sh(vim-lsp) anddevelopment/start-vim-coc.sh(coc).- coc.nvim reported valid links as broken / couldn't resolve — only via
the new
development/start-vim-coc.shlauncher: its generatedcoc-settings.jsonregistered the server withcommand/filetypesbut noinitializationOptions, sowiki_rootnever reached the server and it resolved links against its default (~/vimwiki). Fix: the launcher now emitsinitializationOptionsandsettings.nuwikimirroring the vim-lsp client (autoload/nuwiki/lsp.vims:settings()). Verified with a headless coc.nvim run:[[Notes]]resolves, only genuinely-missing links warn. (Shipped plugin only — no production code change; coc users configure their owncoc-settings.jsonper the README snippet.)
P2 — Moderate (real users hit these)
<Leader>w<Leader>tcollision — upstream = today-in-new-tab; nuwiki bound both<Leader>w<Leader>tand<Leader>w<Leader>mto tomorrow's diary. Fix:<Leader>w<Leader>tnow callsdiary_today_tab(today in a new tab),<Leader>w<Leader>mstays tomorrow — exact upstream parity (lua/nuwiki/keymaps.lua,ftplugin/vimwiki.vim; docs + README updated). Covered bydiary.leader_t_opens_today_in_tab/diary.leader_m_opens_tomorrow.- Generated-section captions hardcoded —
toc_header/toc_header_level,links_header,tags_header(+levels). Fix:crates/nuwiki-lsp/src/config.rs+ server TOC/generate renderers. - On-save autoregen family —
auto_diary_index,auto_generate_links,auto_generate_tags,auto_tags(onlyauto_toc/auto_exportexist). Fix:config.rsRawWiki/WikiConfig+ thedidSavepath. listsym_rejected— rejected glyph-is hardcoded. Fix:config.rsWikiConfig.custom_wiki2html(+_args) andbase_url— external HTML converter hook + export URL prefix. Fix:config.rsHtmlConfig.map_prefix—<Leader>whardcoded across the map layer. Fix:plugin/nuwiki.vim,lua/nuwiki/keymaps.lua,ftplugin/vimwiki.vim.<M-CR>badd-link — was mouse-only (<MiddleMouse>) / command-only (:VimwikiBaddLink); upstream binds<M-CR>→VimwikiBaddLink(confirmed against upstreamftplugin/vimwiki.vim). Fix: added normal-mode<M-CR>→badd_linkin the links group of both clients (lua/nuwiki/keymaps.lua,ftplugin/vimwiki.vim; docs + README updated). Covered bymap[n].<M-CR>in both keymap harnesses.diary_caption_leveldefault divergence — nuwiki defaulted to1, upstream0. Fix:wiki_defaults()incrates/nuwiki-lsp/src/config.rsnow defaultsdiary_caption_level: 0(year captions top-level, months one below), still per-wiki overridable. Testdefaults_carry_vimwiki_per_wiki_keysupdated.diary_start_week_day— removed inc63ec67(weekly diary hardwired to ISO-Monday). Restored as a configurable choice so migrators keep upstream behaviour while new wikis can use ISO weeks. New per-wiki keydiary_weekly_style:iso(default —YYYY-Www, Monday-based, nuwiki's original) ordate/vimwiki(YYYY-MM-DDof the week-start day, upstream parity, honouring the restoreddiary_start_week_day=monday..sunday). Impl:nuwiki_core::date::{WeeklyStyle, WeekStart, DiaryCalendar}own the today/next/prev logic;WikiConfig::diary_calendar()builds it from config; the diary commands (commands.rsdiary_open_relative+ next/prev pivot) use it. Defaults keep existing nuwiki weekly files working (no breaking change). Covered by calendar tests incrates/nuwiki-core/tests/diary.rsand the config round-trip incrates/nuwiki-lsp/tests/index_and_config.rs.
P3 — Niche / low impact
Commands
VimwikiVar— config-var get/set introspection. Fix:plugin/nuwiki.vim.VimwikiShowVersion— print version (trivial). Fix:plugin/nuwiki.vim.VimwikiReturn— no Ex-command (mapping-driven only). Fix:ftplugin/vimwiki.vim.VimwikiTableAlignQvsAlignWcollapsed to onetable_align—gqq(align) vsgww(align w/o resize) distinction lost.VimwikiTableis-nargs=1vs upstream-nargs=*(can't pass cols+rows).VimwikiListChangeLvlis-nargs=?vs upstream-range -nargs=+.VimwikiRebuildTagslacks-bang("rebuild all" variant).:VimwikiSearch/VWSuseslvimgrep, not vimwiki's search engine.VimwikiIndexfamily is buffer-local in nuwiki (upstream defines globally inplugin/); only:…UISelectis a global entry point.VimwikiColorize/NuwikiColorizedrop their argument in the Neovim branch — both are-nargs=1, but the Neovim defs calledcolorize()with no<q-args>(ftplugin/vimwiki.vim:445,517) while the Vim branch passes it. The color name was silently ignored under Neovim (real bug, not just parity). Fix: Neovim command defs now pass<q-args>. While verifying, found a second bug:colorize()inferred visual-vs-normal fromvim.fn.visualmode(), which returns the last session visual mode with stale'</'>marks — so the normal-mode command wrapped a leftover selection instead of the cword.colorize(color, visual)now takes an explicitvisualflag; the command and normal mapping always wrap the cword. Third bug: the commands were not-range, so selecting text and running:VimwikiColorize(which Vim turns into:'<,'>VimwikiColorize) raisedE481: No range allowed. All four command defs are now-rangeand pass the range to the handler — a ranged (visual) invocation wraps the'</'>selection on both clients; thex-mode<Leader>wcmapping passes the visual flag directly. Covered bycmd.VimwikiColorize_uses_arg,cmd.Colorize_ignores_stale_visual_selection,colorize.visual_wraps_selection,cmd.Colorize_range_wraps_selectionintest-keymaps.luaandcolorize.{command_wraps_cword,visual_wraps_selection, ranged_command_no_error}intest-keymaps-vim.vim.- Colour spans aren't concealed — a colorized word shows the literal
<span style="color:…">…</span>markup instead of just the coloured text. Fix:autoload/nuwiki/colors.vimnuwiki#colors#refresh()scans the buffer and defines, per colour, a syntax region that conceals the<span …>/</span>tags (concealends) and paints the wrapped text in the span's actual colour (guifg/ctermfg). Wired from the syntax file (initial + on:colorschemereload), anftpluginTextChangedautocmd, and directly fromcolorize()for immediate effect. The LSP@vimwikiColortoken no longer links toConstantso it doesn't override the real colour on the concealed text in Neovim. Works in Vim, coc, and Neovim (pure syntax +:highlight, no LSP needed). Covered bycolorize.conceal_hides_tags_shows_text(both harnesses) andcolorize.command_conceals_immediately(test-keymaps-vim.vim). VimwikiTableMoveColumn{Left,Right}dispatch to different backing names per client — converged: the Vim-branch commands now callnuwiki#commands#table_move_column_left/right(existing aliases over thetable_move_left/rightimpls), matching the Neovim branch.NuwikiTabIndexlacks-countin the Neovim branch — added-count; also switched both NeovimVimwiki/NuwikiTabIndexfromvim.v.count(always 0 in command context) to<count>, so a:NNuwikiTabIndexcount is now actually honored.VimwikiToggleListItem/Increment/DecrementListItemlack-range(both branches) vs upstream's-range(:350) — no visual-range checkbox toggle / symbol cycle.- Diary-note family lacks
-count(new, 2026-05-31 re-audit) — upstream's:Vimwiki{Make,TabMake,MakeYesterday,MakeTomorrow}DiaryNotecarry-count=0(the count selects the wiki number); nuwiki's diary-note commands declare no count in either branch, andIndex/TabIndexuse bare-countvs upstream-count=0. Fix:ftplugin/vimwiki.vimdiary block (both branches) + thread the count intodiary_today/yesterday/tomorrow. - No
-complete=specs (new) — upstream attaches command-line completion toVimwikiGoto(links),VimwikiRenameFile(files),VimwikiColorize(colours), and the tag commands. nuwiki defines none, so<Tab>completion of page / tag / colour names at the:line is unavailable. Fix:ftplugin/vimwiki.vim(both branches) — VimL completers or LSP-backed. - Minor command-attribute gaps (new) —
VimwikiNormalizeLinklacks upstream's-nargs=?;VimwikiCheckLinkslacks-range. (VimwikiColorize-nargs=1→-nargs=*done — all four defs now match upstream, so a bare:VimwikiColorizeprompts for the colour.) The remaining two would be accepted-but-ignored without handler work, so left open.
Config
auto_header— auto H1-from-filename on new page (server-side).create_link— toggle to suppress link-target creation.dir_link— index file to open when following a directory link.auto_chdir—:cdinto wiki root on open (client-side).bullet_types/cycle_bullets— custom bullet glyphs + wrap-around.commentstring('%%%s') — comment toggling/text-objects.color_tag_template—color_dicpresent; template regex missing.rss_max_items/rss_name—:Rssoutput hardcoded. Fix:HtmlConfig.emoji_enable— emoji substitution.html_header_numbering(+_sym) — numbered HTML headers.valid_html_tags— allowed inline HTML tags in export.generated_links_caption,toc_link_format,markdown_link_ext.list_ignore_newline/text_ignore_newline— export newline handling.
Mappings
- Visual
<CR>normalize-link (visual+covers the same intent). - Insert
<S-CR>multiline list item. gLH/gLL/gLR— upstream binds these as case-variant aliases ofgLh/gLl/gLr(same actions: dedent / indent whole item, renumber all lists; upstreamftplugin/vimwiki.vim:553,555,561). nuwiki has the lowercase forms but not the uppercase-suffix aliases. Cosmetic — same effect, redundant keys.<D-CR>(Cmd+Return) tab-drop alias (new, 2026-05-31 re-audit) — added<D-CR>→follow_link_dropalongside<C-S-CR>in both clients (lua/nuwiki/keymaps.lua,ftplugin/vimwiki.vim); docs updated. Covered bymap[n].<D-CR>in both harnesses.<Leader>w<Leader>mmissing from the Vim global map block (new) —plugin/nuwiki.vim's global family now binds<Leader>w<Leader>m(tomorrow) and<Leader>w<Leader>topens today in a new tab (was the same collision the buffer-local maps had). Covered bymap[n].<Leader>w<Leader>min both harnesses.
Intentional divergences (no action — architectural)
These upstream options have no nuwiki equivalent by design, because nuwiki is an LSP-backed reimplementation rather than a pure-VimL plugin. Listed so future audits don't re-flag them.
nested_syntaxes/automatic_nested_syntaxes— code-fence languages are auto-detected from the fence tag (syntax/vimwiki.vim); always on, no toggle.maxhi— existence-based link highlighting; superseded by LSP diagnostics.conceal*(conceallevel,conceal_onechar_markers, …) — semantic tokens replace conceal.ext2syntax— syntax chosen by extension /syntaxkey automatically.folding(upstream string) — nuwiki usesfolding = 'lsp' | 'expr' | 'off'backed by LSP foldingRange.key_mappings(dict) — replaced by Luamappings.<group>+ theg:nuwiki_no_<group>_mappingsglobals.use_calendar— no calendar.vim integration.global_ext(upstream1) — nuwiki's ftdetect always maps the configured wiki extension(s) to thevimwikifiletype regardless of location; there's no per-wiki "only inside the root" toggle. Effectively always-on, likenested_syntaxes.syntaxdefault name — nuwiki defaults the per-wikisyntaxtovimwiki(its primary syntax) where upstream defaults todefault; a naming difference, not a behavioural one.CJK_length,listing_hl*,schemes_*,w32_dir_enc,menu,rx_todo/tag_format— syntax internals, menu, or Vim/Win shims.
Notes
- Audit confidence: upstream defaults pulled from vimwiki
master; a couple of values (CJK_length,links_space_char) were summarized loosely but don't affect the gap list. - nuwiki adds some commands with no upstream equivalent (e.g.
:NuwikiFindOrphans) — additive, not divergences. - Re-audited 2026-05-31 (config / mappings / commands, three parallel agents
against vimwiki
master). All recent P1/P2/P3 fixes — split/tab link-follow,gl/gLchange-symbol + bare-gl/gLremove-checkbox,<CR>-family create-on-follow,<M-CR>badd,<Leader>w<Leader>t/m,VimwikiColorizearg+range, colour-span conceal — confirmed present and correct in both clients. New gaps from that pass (diary-note-count,-completespecs,<D-CR>, global<Leader>w<Leader>m, plusglobal_ext/syntax-name notes) were added above; no previously-closed item regressed.