Files
nuwiki/development/vimwiki-gap.md
T
gffranco 66bfd61a63
CI / cargo fmt --check (push) Successful in 18s
CI / cargo clippy (push) Successful in 27s
CI / cargo test (push) Successful in 29s
CI / editor keymaps (push) Successful in 1m23s
fix(client): VimwikiColorize passes its {color} arg on Neovim + visual fix
The Neovim command defs for :VimwikiColorize / :NuwikiColorize were
-nargs=1 but called colorize() without <q-args>, so the colour name was
silently dropped and the user was prompted instead (the Vim branch passed
it correctly). Pass <q-args>.

While verifying, found a second bug in the Lua colorize(): it inferred
visual-vs-normal from vim.fn.visualmode(), which returns the *last* visual
mode used in the session along with stale '< / '> marks. So running
:VimwikiColorize in normal mode after any earlier visual selection wrapped
that leftover selection instead of the word under the cursor (produced an
empty, misplaced span). colorize(color, visual) now takes an explicit
visual flag, passed only by the x-mode <Leader>wc mapping; the command and
the normal-mode mapping always wrap the cword.

Tests: cmd.VimwikiColorize_uses_arg, cmd.NuwikiColorize_uses_arg,
cmd.Colorize_ignores_stale_visual_selection, colorize.visual_wraps_selection
in test-keymaps.lua. nvim suite 267, vim suite 254+18, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:18:31 +00:00

12 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 masterautoload/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 commandsVimwikiSplitLink, VimwikiVSplitLink, VimwikiGoBackLink, VimwikiTabnewLink, VimwikiTabDropLink exist 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 in autoload/nuwiki/commands.vim; true :tab drop tab-reuse wired in both clients (lua/nuwiki/commands.lua open_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- gl1 gla gli … plus gL…) has no nuwiki keymap; only :…ChangeSymbol* commands exist. Fix: added normal-mode gl{-,*,#,1,i,I,a,A} (item) + gL… (whole list) in lua/nuwiki/keymaps.lua lists group and ftplugin/vimwiki.vim Vim-branch lists block, wired to the existing list_change_symbol. 1) stays command-only (upstream shadows it with 1.); 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 bare gl/gL to remove-checkbox-item / -in-list for exact upstream parity (lua/nuwiki/keymaps.lua lists block, ftplugin/vimwiki.vim Vim-branch lists block); they share the gl… prefix so they fire after timeoutlen, just like upstream. Remove-done is now command-only: :NuwikiRemoveDone (current list) gained a -bang so :NuwikiRemoveDone! reaches the whole-buffer sweep that gL<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-lsp readfile()s it for the quickfix entry (autoload/lsp/utils/location.vim), which throws E484 for a missing file and aborts the jump (→ no create-on-follow); coc, lacking an explicit open command, fell back to the user's coc.preferences.jumpCommand (→ new tab). The server itself was correct throughout — verified over JSON-RPC that textDocument/definition returns a synthesised location for missing pages and resolves existing links. Fix: stop delegating. nuwiki#commands#follow_link_or_create() / follow_link_drop() now resolve textDocument/definition directly and open the URI ourselves via a shared s:open_definition(open_cmd) helper (autoload/nuwiki/commands.vim) — :edit for <CR>, tab drop for <C-S-CR>. :edit opens 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 by cr.follow_opens_missing_page_in_current_window in development/tests/test-keymaps-vim.vim; manually reproducible via development/start-vim.sh (vim-lsp) and development/start-vim-coc.sh (coc).
  • coc.nvim reported valid links as broken / couldn't resolve — only via the new development/start-vim-coc.sh launcher: its generated coc-settings.json registered the server with command/filetypes but no initializationOptions, so wiki_root never reached the server and it resolved links against its default (~/vimwiki). Fix: the launcher now emits initializationOptions and settings.nuwiki mirroring the vim-lsp client (autoload/nuwiki/lsp.vim s: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 own coc-settings.json per the README snippet.)

P2 — Moderate (real users hit these)

  • <Leader>w<Leader>t collision — upstream = today-in-new-tab; nuwiki = tomorrow's diary. Fix: lua/nuwiki/keymaps.lua, ftplugin/vimwiki.vim.
  • Generated-section captions hardcodedtoc_header / toc_header_level, links_header, tags_header (+levels). Fix: crates/nuwiki-lsp/src/config.rs + server TOC/generate renderers.
  • On-save autoregen familyauto_diary_index, auto_generate_links, auto_generate_tags, auto_tags (only auto_toc / auto_export exist). Fix: config.rs RawWiki/WikiConfig + the didSave path.
  • listsym_rejected — rejected glyph - is hardcoded. Fix: config.rs WikiConfig.
  • custom_wiki2html (+_args) and base_url — external HTML converter hook + export URL prefix. Fix: config.rs HtmlConfig.
  • map_prefix<Leader>w hardcoded across the map layer. Fix: plugin/nuwiki.vim, lua/nuwiki/keymaps.lua, ftplugin/vimwiki.vim.
  • <M-CR> badd-link — missing (badd is mouse-only via <MiddleMouse> / :VimwikiBaddLink). Fix: lua/nuwiki/keymaps.lua, ftplugin/vimwiki.vim.
  • diary_caption_level default divergence — nuwiki 1 vs vimwiki 0. Fix: config.rs:291 (and defaults in lua/nuwiki/config.lua).
  • diary_start_week_daywrongly removed in c63ec67. The removal treated it as a server concern and hardwired the weekly diary to ISO-Monday (crates/nuwiki-core/src/date.rs monday_of_iso_week), but choosing which weekday the diary week begins on is a client-side concern and it matters for parity — non-Monday users lose the upstream option entirely. Fix: restore the config key client-side (lua/nuwiki/config.lua) and thread the week-start through to the diary date logic instead of hardcoding Monday.

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.
  • VimwikiTableAlignQ vs AlignW collapsed to one table_aligngqq (align) vs gww (align w/o resize) distinction lost.
  • VimwikiTable is -nargs=1 vs upstream -nargs=* (can't pass cols+rows).
  • VimwikiListChangeLvl is -nargs=? vs upstream -range -nargs=+.
  • VimwikiRebuildTags lacks -bang ("rebuild all" variant).
  • :VimwikiSearch / VWS uses lvimgrep, not vimwiki's search engine.
  • VimwikiIndex family is buffer-local in nuwiki (upstream defines globally in plugin/); only :…UISelect is a global entry point.
  • VimwikiColorize / NuwikiColorize drop their argument in the Neovim branch — both are -nargs=1, but the Neovim defs called colorize() 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 from vim.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 explicit visual flag passed only by the x-mode <Leader>wc mapping (lua/nuwiki/keymaps.lua); the command and normal mapping always wrap the cword. Covered by cmd.VimwikiColorize_uses_arg, cmd.Colorize_ignores_stale_visual_selection, and colorize.visual_wraps_selection in development/tests/test-keymaps.lua.
  • VimwikiTableMoveColumn{Left,Right} dispatch to different backing names per client — Vim branch → table_move_left/right; Neovim branch → table_move_column_left/right. Harmless today (each name exists in its own impl) but a divergence to converge.
  • NuwikiTabIndex lacks -count in the Neovim branch (:452) while its siblings (VimwikiTabIndex, NuwikiIndex, and the Vim-branch NuwikiTabIndex) all carry it — vim.v.count is still read, so a count is honored inconsistently.
  • VimwikiToggleListItem / Increment / DecrementListItem lack -range (both branches) vs upstream's -range (:350) — no visual-range checkbox toggle / symbol cycle.

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:cd into wiki root on open (client-side).
  • bullet_types / cycle_bullets — custom bullet glyphs + wrap-around.
  • commentstring ('%%%s') — comment toggling/text-objects.
  • color_tag_templatecolor_dic present; template regex missing.
  • rss_max_items / rss_name:Rss output 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 of gLh / gLl / gLr (same actions: dedent / indent whole item, renumber all lists; upstream ftplugin/vimwiki.vim:553,555,561). nuwiki has the lowercase forms but not the uppercase-suffix aliases. Cosmetic — same effect, redundant keys.

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 / syntax key automatically.
  • folding (upstream string) — nuwiki uses folding = 'lsp' | 'expr' | 'off' backed by LSP foldingRange.
  • key_mappings (dict) — replaced by Lua mappings.<group> + the g:nuwiki_no_<group>_mappings globals.
  • use_calendar — no calendar.vim integration.
  • 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.