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

202 lines
12 KiB
Markdown

# vimwiki → nuwiki Parity Gaps
Tracking document for closing the gap between nuwiki and the original
[vimwiki](https://github.com/vimwiki/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)
- [x] **Vim client split/tab link-follow commands**`VimwikiSplitLink`,
`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.
- [x] **`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).
- [x] **`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)
- [x] **`<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).
- [x] **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 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` (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_day`** — **wrongly 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_align``gqq`
(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.
- [x] **`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_template``color_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.