2026-05-31 07:30:22 -03:00
|
|
|
|
# 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)
|
|
|
|
|
|
|
2026-05-31 07:54:32 -03:00
|
|
|
|
- [x] **Vim client split/tab link-follow commands** — `VimwikiSplitLink`,
|
2026-05-31 07:30:22 -03:00
|
|
|
|
`VimwikiVSplitLink`, `VimwikiGoBackLink`, `VimwikiTabnewLink`,
|
|
|
|
|
|
`VimwikiTabDropLink` exist only in the Neovim branch. Vim users lose
|
|
|
|
|
|
split-window link following and back-navigation.
|
2026-05-31 07:54:32 -03:00
|
|
|
|
_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.
|
2026-05-31 08:10:15 -03:00
|
|
|
|
- [x] **`gl<symbol>` change-symbol mappings** — upstream's one-key bullet/number
|
2026-05-31 07:30:22 -03:00
|
|
|
|
symbol change (`gl*` `gl#` `gl-` `gl1` `gla` `gli` … plus `gL…`) has no
|
|
|
|
|
|
nuwiki keymap; only `:…ChangeSymbol*` commands exist.
|
2026-05-31 08:10:15 -03:00
|
|
|
|
_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).
|
2026-05-31 08:41:33 -03:00
|
|
|
|
- [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.
|
2026-05-31 07:30:22 -03:00
|
|
|
|
|
2026-05-31 09:02:52 -03:00
|
|
|
|
## Regressions (reported by users — verify, then fix)
|
|
|
|
|
|
|
2026-05-31 15:00:59 +00:00
|
|
|
|
- [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.)
|
2026-05-31 09:02:52 -03:00
|
|
|
|
|
2026-05-31 07:30:22 -03:00
|
|
|
|
## P2 — Moderate (real users hit these)
|
|
|
|
|
|
|
2026-05-31 16:21:49 +00:00
|
|
|
|
- [x] **`<Leader>w<Leader>t` collision** — upstream = today-in-new-tab; nuwiki
|
|
|
|
|
|
bound both `<Leader>w<Leader>t` and `<Leader>w<Leader>m` to tomorrow's diary.
|
|
|
|
|
|
_Fix:_ `<Leader>w<Leader>t` now calls `diary_today_tab` (today in a new tab),
|
|
|
|
|
|
`<Leader>w<Leader>m` stays tomorrow — exact upstream parity
|
|
|
|
|
|
(`lua/nuwiki/keymaps.lua`, `ftplugin/vimwiki.vim`; docs + README updated).
|
|
|
|
|
|
Covered by `diary.leader_t_opens_today_in_tab` / `diary.leader_m_opens_tomorrow`.
|
2026-05-31 18:44:35 +00:00
|
|
|
|
- [x] **Generated-section captions hardcoded** — TOC/links/tags headings and
|
|
|
|
|
|
their levels were hardcoded (`= Contents =`, `= Generated Links =`, `= Tags =`,
|
|
|
|
|
|
all level 1). _Fix:_ added per-wiki `toc_header`/`toc_header_level`,
|
|
|
|
|
|
`links_header`/`links_header_level`, `tags_header`/`tags_header_level`
|
|
|
|
|
|
(defaults `Contents`/`Generated Links`/`Generated Tags`, level 1 — matching
|
|
|
|
|
|
upstream; this also corrects the tags index heading from `Tags` →
|
|
|
|
|
|
`Generated Tags`). A `caption_line(name, level)` helper emits the markers; the
|
|
|
|
|
|
text + level thread through `toc_edit`/`links_edit`/`tag_links_edit` (+ the
|
|
|
|
|
|
auto_toc save hook) and `find_section_range` matches the configured text so
|
|
|
|
|
|
regen stays idempotent. Tests: `captions_honour_custom_header_and_level`
|
|
|
|
|
|
(`link_health.rs`) + config round-trip in `index_and_config.rs`.
|
2026-05-31 18:55:51 +00:00
|
|
|
|
- [x] **On-save autoregen family** — added per-wiki `auto_generate_links`,
|
|
|
|
|
|
`auto_generate_tags`, `auto_diary_index` (all default `false`, like upstream),
|
|
|
|
|
|
wired into the `did_save` hook (`crates/nuwiki-lsp/src/lib.rs`) mirroring
|
|
|
|
|
|
`auto_toc`: regen runs only when the section already exists
|
|
|
|
|
|
(`links_rebuild_edit` / `tag_links_rebuild_edit`), and `auto_diary_index`
|
|
|
|
|
|
regenerates the diary index when a dated diary *entry* is saved
|
|
|
|
|
|
(`diary_generate_index_edit`, which handles an open/closed/absent index file).
|
|
|
|
|
|
`auto_tags` is an **intentional divergence** (see below): nuwiki re-indexes on
|
|
|
|
|
|
every change, so tag metadata is always fresh — there's no on-disk metadata
|
|
|
|
|
|
file to update on save. Tests: `links_rebuild_edit_only_acts_when_section_present`
|
|
|
|
|
|
(`link_health.rs`), `tag_links_rebuild_edit_only_acts_when_index_present`
|
|
|
|
|
|
(`commands_tags.rs`), config round-trip + defaults (`index_and_config.rs`).
|
2026-05-31 18:33:25 +00:00
|
|
|
|
- [x] **`listsym_rejected`** — the rejected glyph was a hardcoded `const '-'`.
|
|
|
|
|
|
_Fix:_ `ListSyms` gained a `rejected` field + `new_with_rejected()`
|
|
|
|
|
|
(`crates/nuwiki-core/src/listsyms.rs`); per-wiki `listsym_rejected` key (default
|
|
|
|
|
|
`-`) added to `WikiConfig`; `WikiConfig::list_syms()` builds the palette with
|
|
|
|
|
|
it, used by the parse path (`lib.rs`) and the toggle/cycle commands — so a
|
|
|
|
|
|
custom rejected glyph both lexes and round-trips. Tests:
|
|
|
|
|
|
`listsyms::custom_rejected_glyph_is_honoured` + config round-trip in
|
|
|
|
|
|
`index_and_config.rs`.
|
2026-05-31 19:06:42 +00:00
|
|
|
|
- [x] **`custom_wiki2html` (+`_args`)** and **`base_url`** — external HTML
|
|
|
|
|
|
converter hook + export URL prefix. _Fix:_ `HtmlConfig` (`config.rs`) gained
|
|
|
|
|
|
`custom_wiki2html`, `custom_wiki2html_args`, `base_url` (all default `""`,
|
|
|
|
|
|
round-tripped through `RawWiki`/`From`/defaults). `write_page`
|
|
|
|
|
|
(`commands.rs`) now takes a `force` flag and, when `custom_wiki2html` is set,
|
|
|
|
|
|
hands the page to `run_custom_wiki2html()` — which shells out via `sh -c`
|
|
|
|
|
|
with vimwiki's exact arg order (`<cmd> <force> <syntax> <ext> <out_dir>
|
|
|
|
|
|
<in_file> <css> <tpl_path> <tpl_default> <tpl_ext> <root_path> <args>`, `-`
|
|
|
|
|
|
for empty optionals) instead of the built-in renderer. `force` is threaded
|
|
|
|
|
|
through `export_current` (false), `export_all` (its own flag), and the
|
|
|
|
|
|
`did_save` auto-export path (false). `write_rss` now prefixes the channel +
|
|
|
|
|
|
item links with `base_url` (`<base_url><diary_rel_path>/<date>.html`) when
|
|
|
|
|
|
set, falling back to the entry's `file://` URI otherwise. Tests:
|
|
|
|
|
|
`write_page_invokes_custom_wiki2html_converter`,
|
|
|
|
|
|
`write_rss_uses_base_url_for_public_links` (`html_export.rs`), config
|
|
|
|
|
|
round-trip + defaults (`index_and_config.rs`).
|
2026-05-31 19:18:06 +00:00
|
|
|
|
- [x] **`map_prefix`** — `<Leader>w` was hardcoded across the map layer.
|
|
|
|
|
|
_Fix:_ mirror vimwiki's `g:vimwiki_map_prefix` with a configurable prefix
|
|
|
|
|
|
(Neovim `map_prefix` setup option, default `'<Leader>w'`; Vim
|
|
|
|
|
|
`g:nuwiki_map_prefix`). The whole wiki command family is now built from the
|
|
|
|
|
|
prefix — both entry-point globals (`lua/nuwiki/init.lua`,
|
|
|
|
|
|
`plugin/nuwiki.vim`, via `:exe`) and buffer-local maps
|
|
|
|
|
|
(`lua/nuwiki/keymaps.lua`, `ftplugin/vimwiki.vim`). Setting a custom prefix
|
|
|
|
|
|
relocates `<prefix>{w,t,s,i,n,d,r,c,h,hh,ha}` and `<prefix><Leader>{w,y,t,m,
|
|
|
|
|
|
i}` and leaves nothing under the old `<Leader>w*`. Tests: new
|
|
|
|
|
|
`test-keymaps-vim-prefix.vim` harness (21 cases, driven by
|
|
|
|
|
|
`test-keymaps-vim.sh`) + `map_prefix.relocates_wiki_family`
|
|
|
|
|
|
(`test-keymaps.lua`). Docs: README, `doc/nuwiki.txt`, lua config comment.
|
2026-05-31 16:21:49 +00:00
|
|
|
|
- [x] **`<M-CR>` badd-link** — was mouse-only (`<MiddleMouse>`) / command-only
|
|
|
|
|
|
(`:VimwikiBaddLink`); upstream binds `<M-CR>` → `VimwikiBaddLink` (confirmed
|
|
|
|
|
|
against upstream `ftplugin/vimwiki.vim`). _Fix:_ added normal-mode `<M-CR>` →
|
|
|
|
|
|
`badd_link` in the links group of both clients (`lua/nuwiki/keymaps.lua`,
|
|
|
|
|
|
`ftplugin/vimwiki.vim`; docs + README updated). Covered by `map[n].<M-CR>` in
|
|
|
|
|
|
both keymap harnesses.
|
2026-05-31 16:50:59 +00:00
|
|
|
|
- [x] **`diary_caption_level` default divergence** — nuwiki defaulted to `1`,
|
|
|
|
|
|
upstream `0`. _Fix:_ `wiki_defaults()` in `crates/nuwiki-lsp/src/config.rs` now
|
|
|
|
|
|
defaults `diary_caption_level: 0` (year captions top-level, months one below),
|
|
|
|
|
|
still per-wiki overridable. Test `defaults_carry_vimwiki_per_wiki_keys` updated.
|
2026-05-31 17:06:09 +00:00
|
|
|
|
- [x] **`diary_start_week_day`** — removed in `c63ec67` (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 key
|
|
|
|
|
|
`diary_weekly_style`: `iso` (default — `YYYY-Www`, Monday-based, nuwiki's
|
|
|
|
|
|
original) or `date`/`vimwiki` (`YYYY-MM-DD` of the week-start day, upstream
|
|
|
|
|
|
parity, honouring the restored `diary_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.rs` `diary_open_relative` + next/prev pivot) use
|
|
|
|
|
|
it. Defaults keep existing nuwiki weekly files working (no breaking change).
|
|
|
|
|
|
Covered by calendar tests in `crates/nuwiki-core/tests/diary.rs` and the
|
|
|
|
|
|
config round-trip in `crates/nuwiki-lsp/tests/index_and_config.rs`.
|
2026-05-31 07:30:22 -03:00
|
|
|
|
|
|
|
|
|
|
## 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.
|
2026-05-31 20:10:53 +00:00
|
|
|
|
- [x] `VimwikiTable` was `-nargs=1` vs upstream `-nargs=*` (couldn't pass
|
|
|
|
|
|
cols+rows). _Fix:_ all four defs (Vim+Neovim × Vimwiki+Nuwiki) are now
|
|
|
|
|
|
`-nargs=*` and forward `<f-args>` to `table_insert` (which already parsed
|
|
|
|
|
|
cols/rows). Covered by `cmd.VimwikiTable_passes_cols_and_rows`
|
|
|
|
|
|
(`test-keymaps.lua`, asserts a `:VimwikiTable 4 3` → 4-col, 3-row table) and
|
|
|
|
|
|
`cmd.VimwikiTable_accepts_cols_rows` (`test-keymaps-vim.vim`, no E488).
|
2026-05-31 20:28:39 +00:00
|
|
|
|
Follow-up (same pass): the no-arg **default cols** diverged (nuwiki `3` vs
|
|
|
|
|
|
upstream `5`; rows `2` already matched — confirmed against upstream
|
|
|
|
|
|
`vimwiki#tbl#create`). Aligned both backing fns to default 5 cols.
|
2026-05-31 20:16:10 +00:00
|
|
|
|
- [x] `VimwikiListChangeLvl` was `-nargs=?` (range-less) vs upstream
|
|
|
|
|
|
`-range -nargs=+`. _Fix:_ all four defs are now `-range -nargs=+` passing
|
|
|
|
|
|
`<line1>, <line2>, <f-args>`; `list_change_lvl(line1, line2, direction,
|
|
|
|
|
|
[plus_children])` (both clients) parses the required direction + optional
|
|
|
|
|
|
subtree flag and applies the level change to every list item in the range
|
|
|
|
|
|
via the existing `over_range` helper. Covered by
|
|
|
|
|
|
`cmd.ListChangeLvl_range_indents` (`test-keymaps.lua`) and
|
|
|
|
|
|
`cmd.VimwikiListChangeLvl_accepts_range_and_args` (`test-keymaps-vim.vim`,
|
|
|
|
|
|
no E481/E488).
|
2026-05-31 20:28:39 +00:00
|
|
|
|
- [ ] **Neovim `follow_link_or_create` is botched** _(new, 2026-05-31
|
|
|
|
|
|
command-attribute audit)_ — `lua/nuwiki/commands.lua` calls
|
|
|
|
|
|
`vim.lsp.buf.definition()` **twice** with dead code between
|
|
|
|
|
|
(`local p = pos_args()[1]` … `local _ = p`), and never does the bare-word →
|
|
|
|
|
|
`[[link]]` wrap its docstring promises (the Vim side does, via
|
|
|
|
|
|
`s:wrap_word_under_cursor`). So on Neovim, `<CR>` on a bare word doesn't
|
|
|
|
|
|
create/follow a link, and link-follow fires a redundant second jump. _Fix:_
|
|
|
|
|
|
rewrite to wrap-then-jump once, mirroring the Vim path.
|
|
|
|
|
|
- [ ] **Neovim SplitLink/VSplitLink skip the bare-word wrap** _(new, same
|
|
|
|
|
|
audit)_ — the Neovim defs dispatch to raw `vim.lsp.buf.definition()` while
|
|
|
|
|
|
the Vim defs (and Neovim `FollowLink`/`TabnewLink`) use
|
|
|
|
|
|
`follow_link_or_create`. Once the above is fixed, route Neovim
|
|
|
|
|
|
Split/VSplitLink through `follow_link_or_create` too for cross-client parity.
|
2026-05-31 17:57:03 +00:00
|
|
|
|
- [x] `VimwikiRebuildTags` `-bang` ("rebuild all") — `:…RebuildTags!` now passes
|
|
|
|
|
|
`{ all: true }`; the server (`tags_rebuild`) re-indexes **every** configured
|
|
|
|
|
|
wiki (via `wikis_snapshot()`) instead of just the current one. `-bang` added to
|
|
|
|
|
|
all four command defs.
|
2026-05-31 07:30:22 -03:00
|
|
|
|
- [ ] `: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.
|
2026-05-31 15:18:31 +00:00
|
|
|
|
- [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.
|
2026-05-31 15:37:09 +00:00
|
|
|
|
`colorize(color, visual)` now takes an explicit `visual` flag; 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`) raised `E481: No range allowed`. All four
|
|
|
|
|
|
command defs are now `-range` and pass the range to the handler — a ranged
|
|
|
|
|
|
(visual) invocation wraps the `'<`/`'>` selection on both clients; the
|
|
|
|
|
|
`x`-mode `<Leader>wc` mapping passes the visual flag directly. Covered by
|
|
|
|
|
|
`cmd.VimwikiColorize_uses_arg`, `cmd.Colorize_ignores_stale_visual_selection`,
|
|
|
|
|
|
`colorize.visual_wraps_selection`, `cmd.Colorize_range_wraps_selection` in
|
|
|
|
|
|
`test-keymaps.lua` and `colorize.{command_wraps_cword,visual_wraps_selection,
|
|
|
|
|
|
ranged_command_no_error}` in `test-keymaps-vim.vim`.
|
2026-05-31 16:01:21 +00:00
|
|
|
|
- [x] **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.vim` `nuwiki#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 `:colorscheme`
|
|
|
|
|
|
reload), an `ftplugin` `TextChanged` autocmd, and directly from `colorize()`
|
|
|
|
|
|
for immediate effect. The LSP `@vimwikiColor` token no longer links to
|
|
|
|
|
|
`Constant` so 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 by `colorize.conceal_hides_tags_shows_text` (both harnesses)
|
|
|
|
|
|
and `colorize.command_conceals_immediately` (`test-keymaps-vim.vim`).
|
2026-05-31 17:28:06 +00:00
|
|
|
|
- [x] **`VimwikiTableMoveColumn{Left,Right}` dispatch to different backing names
|
|
|
|
|
|
per client** — converged: the Vim-branch commands now call
|
|
|
|
|
|
`nuwiki#commands#table_move_column_left/right` (existing aliases over the
|
|
|
|
|
|
`table_move_left/right` impls), matching the Neovim branch.
|
|
|
|
|
|
- [x] **`NuwikiTabIndex` lacks `-count` in the Neovim branch** — added `-count`;
|
2026-05-31 18:24:22 +00:00
|
|
|
|
also switched the Neovim `Index`/`TabIndex` family (`Vimwiki/NuwikiTabIndex`
|
|
|
|
|
|
and `Vimwiki/NuwikiIndex`) from `vim.v.count` (always 0 in command context) to
|
|
|
|
|
|
`<count>`, so a `:2NuwikiIndex` / `:3NuwikiTabIndex` count is now honored.
|
|
|
|
|
|
(The `Index` half was caught by the 2026-05-31 second re-audit and fixed then.)
|
2026-05-31 17:57:03 +00:00
|
|
|
|
- [x] **`VimwikiToggleListItem` / `Increment` / `DecrementListItem` `-range`** —
|
|
|
|
|
|
all three (both branches) are now `-range`; the client loops the per-line op
|
|
|
|
|
|
over `[<line1>, <line2>]` (`toggle_list_item_range` / `list_cycle_symbol_range`).
|
|
|
|
|
|
The server edits are version-less single-line, so each line's edit applies
|
|
|
|
|
|
independently — no server protocol change needed. Covered by
|
|
|
|
|
|
`cmd.toggle_list_item_range` in `test-keymaps.lua`.
|
2026-05-31 16:44:28 +00:00
|
|
|
|
- [ ] **Diary-note family lacks `-count`** _(new, 2026-05-31 re-audit)_ — upstream's
|
|
|
|
|
|
`:Vimwiki{Make,TabMake,MakeYesterday,MakeTomorrow}DiaryNote` carry `-count=0`
|
|
|
|
|
|
(the count selects the wiki number); nuwiki's diary-note commands declare no
|
2026-05-31 20:10:53 +00:00
|
|
|
|
count in either branch. _Fix:_ `ftplugin/vimwiki.vim` diary block (both
|
|
|
|
|
|
branches) + thread the count into `diary_today/yesterday/tomorrow` + server
|
|
|
|
|
|
diary commands (accept an optional `wiki` selector). _(The `Index`/`TabIndex`
|
|
|
|
|
|
half is done: all four defs now use upstream's `-count=0` instead of bare
|
|
|
|
|
|
`-count`; `wiki_index`/`wiki_tab_index` already map the count to the wiki
|
|
|
|
|
|
number.)_
|
2026-05-31 20:40:22 +00:00
|
|
|
|
- [x] **`-complete=` specs** _(new; done 2026-05-31 command-attribute pass)_ —
|
|
|
|
|
|
upstream attaches command-line completion to several commands; nuwiki had
|
|
|
|
|
|
none, so `<Tab>` at the `:` line never completed page / tag / colour names.
|
|
|
|
|
|
_Fix:_ new `autoload/nuwiki/complete.vim` with pure client-side, synchronous
|
|
|
|
|
|
completers (config + filesystem, never the LSP, so they work under vim-lsp,
|
|
|
|
|
|
coc and Neovim alike), wired via `-complete=customlist,…` into all branches:
|
|
|
|
|
|
- `nuwiki#complete#pages` → `VimwikiGoto`/`NuwikiGoto` (globs every wiki
|
|
|
|
|
|
root's `*<ext>` files → root-relative page names).
|
|
|
|
|
|
- `nuwiki#complete#colors` → `VimwikiColorize`/`NuwikiColorize` (keys from a
|
|
|
|
|
|
configured `color_dic` + colours already used in buffer `color:…` spans).
|
|
|
|
|
|
- `nuwiki#complete#tags` → `VimwikiSearchTags`/`GenerateTagLinks`/
|
|
|
|
|
|
`GenerateTags` (+ Nuwiki forms) — scans the wikis' files for `:tag:` runs
|
|
|
|
|
|
(the tag index lives in the server, which a synchronous completer can't
|
|
|
|
|
|
query; the file scan reads the same source the server indexes).
|
|
|
|
|
|
**Divergence (documented):** no file completer for `VimwikiRenameFile` —
|
|
|
|
|
|
upstream completes a new-name arg because it renames itself, but nuwiki
|
|
|
|
|
|
delegates renaming to the LSP rename request (`:LspRename`/coc), which drives
|
|
|
|
|
|
its own prompt and takes no filename argument. Covered by
|
|
|
|
|
|
`complete.pages_globs_and_filters`, `complete.tags_scans_wiki_files`,
|
|
|
|
|
|
`complete.colors_from_buffer_spans` (`test-keymaps-vim.vim`).
|
2026-05-31 17:57:03 +00:00
|
|
|
|
- [x] **Minor command-attribute gaps** _(new)_ — all now real, not cosmetic:
|
|
|
|
|
|
`VimwikiNormalizeLink` is `-nargs=?` and with `1` wraps the `'<`/`'>` selection
|
|
|
|
|
|
(`wrap_visual_as_wikilink`, both clients; the `x`-mode `+` passes it too);
|
|
|
|
|
|
`VimwikiCheckLinks` is `-range` and a ranged invocation filters the report to
|
|
|
|
|
|
the current buffer's selected lines; `VimwikiColorize` `-nargs=1`→`-nargs=*`
|
|
|
|
|
|
(bare `:VimwikiColorize` prompts). Covered by
|
|
|
|
|
|
`normalize.visual_wraps_selection` (vim) /
|
|
|
|
|
|
`cmd.normalize_link_visual_wraps_selection` (nvim).
|
2026-05-31 20:20:43 +00:00
|
|
|
|
- [x] **`VimwikiSplitLink` / `VimwikiVSplitLink` lack `-nargs=*`** _(new,
|
|
|
|
|
|
2026-05-31 third re-audit; corrected during the 2026-05-31 command-attribute
|
|
|
|
|
|
pass)_ — the earlier note was wrong: upstream's optional args are NOT a target
|
|
|
|
|
|
link but `reuse_other_split_window` (a:1) and `move_cursor` (a:2) — the link
|
|
|
|
|
|
is always the one under the cursor (`vimwiki#base#follow_link`). nuwiki's defs
|
|
|
|
|
|
took no args, so `:VimwikiSplitLink 0 1` (upstream muscle memory / migrated
|
|
|
|
|
|
scripts) raised E488. _Fix:_ all eight defs (both clients × Split/VSplit ×
|
|
|
|
|
|
Vimwiki/Nuwiki) are now `-nargs=*`, restoring signature parity. **Divergence
|
|
|
|
|
|
(documented):** the two flags are *accepted but not acted on* — nuwiki always
|
|
|
|
|
|
opens a fresh split and follows in it, because the follow is an async LSP
|
|
|
|
|
|
jump and honoring `move_cursor`/`reuse` would require threading a completion
|
|
|
|
|
|
callback through that path (disproportionate for this rarely-used arg form;
|
|
|
|
|
|
the no-arg case — the 99% path — is fully equivalent). Covered by
|
|
|
|
|
|
`cmd.VimwikiSplitLink_accepts_args` (`test-keymaps-vim.vim`, no E488).
|
2026-05-31 07:30:22 -03:00
|
|
|
|
|
|
|
|
|
|
### 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`.
|
2026-05-31 19:22:52 +00:00
|
|
|
|
- [ ] **RSS feed structure fidelity** _(new, 2026-05-31 base_url audit)_ —
|
|
|
|
|
|
nuwiki's `write_rss` is intentionally minimal (title/link/guid). Upstream
|
|
|
|
|
|
emits more: channel `<link>` points at the diary index page
|
|
|
|
|
|
(`base_url + diary_rel_path + diary_index + .html`, nuwiki uses bare
|
|
|
|
|
|
`base_url`); per-item `<guid isPermaLink="false">` holds the bare date
|
|
|
|
|
|
basename (nuwiki uses the full URL, no attribute); plus `<atom:link rel=
|
|
|
|
|
|
"self">`, channel/item `<pubDate>` (from mtime), and a `<![CDATA[…]]>`
|
|
|
|
|
|
rendered-HTML body per item. `base_url`'s *scope* is faithful (RSS-only,
|
|
|
|
|
|
not inter-page links) and the `custom_wiki2html` arg contract is an exact
|
|
|
|
|
|
match — only the feed document shape diverges.
|
2026-05-31 07:30:22 -03:00
|
|
|
|
- [ ] `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.
|
2026-05-31 09:02:59 -03:00
|
|
|
|
- [ ] `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.
|
2026-05-31 17:28:06 +00:00
|
|
|
|
- [x] **`<D-CR>` (Cmd+Return) tab-drop alias** _(new, 2026-05-31 re-audit)_ —
|
|
|
|
|
|
added `<D-CR>` → `follow_link_drop` alongside `<C-S-CR>` in both clients
|
|
|
|
|
|
(`lua/nuwiki/keymaps.lua`, `ftplugin/vimwiki.vim`); docs updated. Covered by
|
|
|
|
|
|
`map[n].<D-CR>` in both harnesses.
|
|
|
|
|
|
- [x] **`<Leader>w<Leader>m` missing from the Vim *global* map block** _(new)_ —
|
|
|
|
|
|
`plugin/nuwiki.vim`'s global family now binds `<Leader>w<Leader>m` (tomorrow)
|
|
|
|
|
|
and `<Leader>w<Leader>t` opens today in a new tab (was the same collision the
|
|
|
|
|
|
buffer-local maps had). Covered by `map[n].<Leader>w<Leader>m` in both harnesses.
|
2026-05-31 19:22:52 +00:00
|
|
|
|
- [x] **`<Leader>w<Leader>m` missing from the Neovim *global* map block**
|
|
|
|
|
|
_(new, 2026-05-31 map_prefix audit)_ — the same collision survived in
|
|
|
|
|
|
`lua/nuwiki/init.lua`'s `_setup_global_mappings`: `<prefix><Leader>t` was
|
|
|
|
|
|
bound to tomorrow and `<prefix><Leader>m` (tomorrow) was absent entirely.
|
|
|
|
|
|
Fixed so `<prefix><Leader>t` opens today in a new tab and `<prefix><Leader>m`
|
|
|
|
|
|
is tomorrow — now consistent with the Vim global side + upstream. Covered by
|
|
|
|
|
|
`global_maps.diary_tab_and_tomorrow_targets` (`test-keymaps.lua`).
|
2026-05-31 07:30:22 -03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 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.
|
2026-05-31 18:55:51 +00:00
|
|
|
|
- `auto_tags` (upstream `0`) — upstream auto-updates an on-disk tag *metadata*
|
|
|
|
|
|
file on save. nuwiki has no such file: the LSP re-indexes tags on every
|
|
|
|
|
|
`didChange`, so tag search/jump/completion are always fresh. The setting's
|
|
|
|
|
|
intent is therefore always satisfied (the `auto_generate_tags` regen of the
|
|
|
|
|
|
in-buffer links section is the configurable on-save piece).
|
2026-05-31 18:24:22 +00:00
|
|
|
|
- Mouse maps (`<2-LeftMouse>`, `<MiddleMouse>`, …) — upstream binds them
|
|
|
|
|
|
unconditionally; nuwiki ships them **opt-in** (`mappings.mouse` /
|
|
|
|
|
|
`g:nuwiki_mouse_mappings`). Deliberate, so they're not always-on.
|
2026-05-31 16:44:28 +00:00
|
|
|
|
- `global_ext` (upstream `1`) — nuwiki's ftdetect always maps the configured
|
|
|
|
|
|
wiki extension(s) to the `vimwiki` filetype regardless of location; there's no
|
|
|
|
|
|
per-wiki "only inside the root" toggle. Effectively always-on, like
|
|
|
|
|
|
`nested_syntaxes`.
|
|
|
|
|
|
- `syntax` default name — nuwiki defaults the per-wiki `syntax` to `vimwiki` (its
|
|
|
|
|
|
primary syntax) where upstream defaults to `default`; a naming difference, not
|
|
|
|
|
|
a behavioural one.
|
2026-05-31 07:30:22 -03:00
|
|
|
|
- `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.
|
2026-05-31 16:44:28 +00:00
|
|
|
|
- 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`/`gL` change-symbol + bare-`gl`/`gL` remove-checkbox, `<CR>`-family
|
|
|
|
|
|
create-on-follow, `<M-CR>` badd, `<Leader>w<Leader>t`/`m`, `VimwikiColorize`
|
|
|
|
|
|
arg+range, colour-span conceal — confirmed present and correct in **both**
|
|
|
|
|
|
clients. New gaps from that pass (diary-note `-count`, `-complete` specs,
|
|
|
|
|
|
`<D-CR>`, global `<Leader>w<Leader>m`, plus `global_ext`/`syntax`-name notes)
|
|
|
|
|
|
were added above; no previously-closed item regressed.
|
2026-05-31 18:24:22 +00:00
|
|
|
|
- Re-audited again 2026-05-31 (third pass) after the range/bang/visual and
|
|
|
|
|
|
diary-week work. All those fixes confirmed in both clients; no regressions.
|
|
|
|
|
|
Confirmed Neovim **does** bind the text objects (`nuwiki.textobjects.attach`).
|
|
|
|
|
|
Found + fixed an oversight (Neovim `Vimwiki/NuwikiIndex` still read
|
|
|
|
|
|
`vim.v.count`; now `<count>`, completing the `TabIndex` fix). New gaps logged:
|
|
|
|
|
|
`VimwikiSplitLink`/`VSplitLink` missing `-nargs=*`; mouse-maps-opt-in noted as
|
|
|
|
|
|
an intentional divergence. Config pass found no new gaps; all shipped defaults
|
|
|
|
|
|
match upstream except the documented `syntax`-name divergence.
|