Commit Graph

19 Commits

Author SHA1 Message Date
gffranco 9441fe918c fix(parity): close the 2026-06-02 re-audit config/command findings
CI / cargo fmt --check (push) Successful in 19s
CI / cargo clippy (push) Successful in 37s
CI / cargo test (push) Successful in 29s
CI / editor keymaps (push) Successful in 1m36s
Implements the remaining fourth-pass findings (gap doc updated):

- list_margin: rework to upstream's buffer-side meaning. Drop the
  nuwiki-only HTML em-margin (renderer field/method + render_page_html
  param removed) and prepend max(0, list_margin) leading spaces to every
  generated bullet in build_toc_text / build_links_text /
  build_tag_links_text / diary::build_index_body; headings stay at col 0.
  From<RawWiki> derives 0 for markdown wikis when unset. Negatives can't
  resolve 'shiftwidth' server-side, so they collapse to zero indent
  (documented divergence).

- diary_months: per-wiki Vec<String> (default 12 English names), threaded
  into the diary-index month labels; missing/empty slots fall back to the
  English name.

- diary_caption_level: widen u8 -> i8 so vimwiki's -1 (min: -1) parses;
  build_index_body clamps < 0 to base tree level 0.

- VimwikiRemoveDone: regain upstream's -range. All four defs are now
  -bang -range, dispatched via remove_done(bang, range, l1, l2) in both
  clients: ! -> whole buffer, explicit range -> new list_remove_done_range
  ({range:[l1-1,l2-1]}), else current list. Server remove_done_edit gained
  an Option<(u32,u32)> range that filters whole-doc victims by start line.

markdown_header_style is deferred: the generators emit vimwiki syntax only
(caption_line never writes markdown headers), so there's no markdown header
to attach the style to. Logged as the "generated-content is vimwiki-only"
intentional divergence pending a later markdown generated-content effort.

Tests: list_margin indent, markdown list_margin-0 default, diary_months
custom + fallback, negative caption_level clamp/parse, ranged remove-done
(server + both keymap harnesses). 553 lsp/core tests pass; clippy clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 10:50:38 +00:00
gffranco 079e7246ac fix(lists): VimwikiToggleRejectedListItem -range parity (P3)
CI / cargo fmt --check (push) Successful in 7m3s
CI / cargo clippy (push) Successful in 17m14s
CI / cargo test (push) Successful in 31m54s
CI / editor keymaps (push) Successful in 1m51s
Upstream's :VimwikiToggleRejectedListItem is -range and binds glx in
visual mode; nuwiki's four defs were bare, so a ranged invocation raised
E481 and acted cursor-only. Same -range class already fixed for
ToggleListItem/Increment/Decrement -- ToggleRejected was missed.

All four defs (Vim+Neovim x Vimwiki*/Nuwiki*) are now -range, routed
through a new reject_list_item_range(l1, l2) looping over_range in both
clients, mirroring toggle_list_item_range. Visual glx stays cursor-only,
consistent with its <C-Space>/gln/glp siblings.

Also logs the 2026-06-02 re-audit findings in development/vimwiki-gap.md:
RemoveDone lost -range (low pri); config gaps list_margin
semantics/markdown-default, diary_months, markdown_header_style,
diary_caption_level=-1; and the path_html/template_path default-location
divergences. Mappings audit came back clean.

Tests: cmd.reject_list_item_range (test-keymaps.lua),
cmd.VimwikiToggleRejectedListItem_accepts_range (test-keymaps-vim.vim).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 01:02:48 +00:00
gffranco 88114a65a4 test: land the vim diary -count cases + dedup the lua one (follow-up to 2da2168)
CI / cargo fmt --check (push) Successful in 32s
CI / cargo clippy (push) Successful in 35s
CI / cargo test (push) Successful in 27s
CI / editor keymaps (push) Successful in 1m25s
2da2168's diary test edits landed unevenly: the lua
cmd.VimwikiMakeDiaryNote_has_count case got inserted twice, and the two vim
cases (cmd.Vimwiki{MakeDiaryNote,DiaryIndex}_accepts_count) the commit message
referenced never landed (the Edit had no-matched). Remove the lua duplicate and
add the two vim cases before the harness wrap-up. lua 284, vim 274/18/21, all
0 failed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 22:35:41 +00:00
gffranco 3b3d8ca782 feat(commands): command-line completion for Goto/Colorize/tag commands (P3)
CI / cargo fmt --check (push) Successful in 37s
CI / cargo clippy (push) Successful in 39s
CI / cargo test (push) Successful in 37s
CI / editor keymaps (push) Successful in 1m29s
Upstream attaches -complete= to several commands; nuwiki had none, so <Tab>
at the : line never completed page/tag/colour names. New
autoload/nuwiki/complete.vim adds pure client-side, synchronous completers
(config + filesystem, never the LSP — so they work under vim-lsp, coc and
Neovim), wired via -complete=customlist into all command contexts:

- nuwiki#complete#pages → VimwikiGoto/NuwikiGoto (glob wiki roots for page names)
- nuwiki#complete#colors → VimwikiColorize/NuwikiColorize (color_dic keys +
  colours already used in buffer color:… spans)
- nuwiki#complete#tags → VimwikiSearchTags/GenerateTagLinks/GenerateTags (+Nuwiki)
  (scan wiki files for :tag: runs — the tag index is server-side and a
  synchronous completer can't query it, so we read the same source it indexes)

Documented divergence: no file completer for VimwikiRenameFile — nuwiki
delegates renaming to the LSP rename request (no filename arg to complete),
unlike upstream which renames itself.

Tests: complete.{pages_globs_and_filters,tags_scans_wiki_files,
colors_from_buffer_spans} (test-keymaps-vim.vim). Both harnesses green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:40:22 +00:00
gffranco acaaf107b4 feat(commands): VimwikiSplitLink/VSplitLink -nargs=* signature parity (P3)
CI / cargo fmt --check (push) Successful in 22s
CI / cargo clippy (push) Successful in 26s
CI / cargo test (push) Successful in 1m5s
CI / editor keymaps (push) Successful in 1m35s
Upstream's :Vimwiki[V]SplitLink take optional reuse_other_split_window +
move_cursor flags (the link is always the one under the cursor); nuwiki's defs
took no args, so `:VimwikiSplitLink 0 1` raised E488. All eight defs (both
clients × Split/VSplit × Vimwiki/Nuwiki) are now -nargs=*, restoring signature
parity for migrated configs/scripts.

Documented divergence: the two flags are accepted but not acted on — nuwiki
always opens a fresh split and follows in it. Honoring move_cursor/reuse would
require threading a completion callback through the async LSP follow path,
disproportionate for this rarely-used arg form; the no-arg path (99% case) is
fully equivalent. The gap-doc note (which wrongly described the args as a
"target link") is corrected.

Test: cmd.VimwikiSplitLink_accepts_args (test-keymaps-vim.vim, no E488).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:20:43 +00:00
gffranco 4710ba03c8 feat(commands): VimwikiListChangeLvl -range -nargs=+ (P3 parity)
CI / cargo fmt --check (push) Successful in 17s
CI / cargo clippy (push) Successful in 28s
CI / cargo test (push) Successful in 50s
CI / editor keymaps (push) Successful in 1m58s
Upstream is `-range -nargs=+` (change_level(line1, line2, direction,
plus_children)); nuwiki was -nargs=? and range-less, so `:1,3VimwikiListChangeLvl
increase 0` raised E481/E488 and the level change never spanned a selection.

All four defs (Vim+Neovim × Vimwiki+Nuwiki) are now -range -nargs=+ and forward
<line1>, <line2>, <f-args>. list_change_lvl(line1, line2, direction,
[plus_children]) (both clients) parses the required direction + optional subtree
flag and applies the change to every list item in the range via the existing
over_range helper.

Tests: cmd.ListChangeLvl_range_indents (test-keymaps.lua) +
cmd.VimwikiListChangeLvl_accepts_range_and_args (test-keymaps-vim.vim).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:16:10 +00:00
gffranco a7f7e8e61f feat(commands): VimwikiTable -nargs=* + Index/TabIndex -count=0 (P3 parity)
CI / cargo fmt --check (push) Successful in 34s
CI / cargo clippy (push) Successful in 21s
CI / cargo test (push) Successful in 30s
CI / editor keymaps (push) Successful in 1m34s
Two command-attribute parity fixes (audited against upstream vimwiki master):

- VimwikiTable / NuwikiTable were -nargs=1 and called table_insert() with no
  args, so `:VimwikiTable 4 3` raised E488 and cols/rows were unreachable.
  All four defs (Vim+Neovim × Vimwiki+Nuwiki) are now -nargs=* and forward
  <f-args>; the backing table_insert already parsed cols (a:1) + rows (a:2).

- VimwikiIndex/TabIndex (and Nuwiki forms) switch from bare -count to
  upstream's -count=0. Behavior is unchanged (both default count to 0;
  wiki_index already maps a count to the 1-indexed wiki number) — this just
  matches the upstream declaration exactly.

Tests: cmd.VimwikiTable_passes_cols_and_rows (test-keymaps.lua — asserts a
4-col/3-row table) and cmd.VimwikiTable_accepts_cols_rows (test-keymaps-vim.vim
— no E488). gap doc updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:10:53 +00:00
gffranco db9c1c5c11 feat: real range/bang/visual handling for the deferred command gaps
CI / cargo fmt --check (push) Successful in 27s
CI / cargo clippy (push) Successful in 22s
CI / cargo test (push) Successful in 53s
CI / editor keymaps (push) Successful in 1m29s
Implements the four items previously left as "needs handler work" — all
fully wired, not cosmetic.

- ToggleListItem / IncrementListItem / DecrementListItem are now -range
  (both clients). The client loops the per-line op over [<line1>,<line2>]
  (toggle_list_item_range / list_cycle_symbol_range). The server's edits are
  version-less single-line WorkspaceEdits, so each line applies independently
  — no server protocol change. `:'<,'>VimwikiToggleListItem` toggles the whole
  selection.
- VimwikiRebuildTags gains -bang: `:…RebuildTags!` passes { all: true } and
  the server (tags_rebuild) re-indexes every configured wiki via
  wikis_snapshot(), not just the current one.
- VimwikiNormalizeLink is -nargs=?: with `1` (upstream's visual flag; the
  x-mode `+` mapping now passes it) it wraps the '< / '> selection as
  [[selection]] (new wrap_visual_as_wikilink in both clients).
- VimwikiCheckLinks is -range: a ranged invocation filters the broken-link
  report to the current buffer's selected lines (client-side filter in
  results_to_qf / check_links).

Tests: cmd.toggle_list_item_range + cmd.normalize_link_visual_wraps_selection
(test-keymaps.lua), normalize.visual_wraps_selection (test-keymaps-vim.vim).
README + doc/nuwiki.txt + gap doc updated. fmt/clippy clean; nvim 274,
vim 266+18, all Rust tests + config-parity green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 17:57:03 +00:00
gffranco 212b300fb4 fix(client): small mapping/command-attribute parity gaps
CI / cargo fmt --check (push) Successful in 37s
CI / cargo clippy (push) Successful in 24s
CI / cargo test (push) Successful in 33s
CI / editor keymaps (push) Successful in 1m44s
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>
2026-05-31 17:28:06 +00:00
gffranco 086455e19b fix(client): P2 diary tab collision + <M-CR> badd-link parity
CI / cargo fmt --check (push) Successful in 36s
CI / cargo clippy (push) Successful in 40s
CI / cargo test (push) Successful in 32s
CI / editor keymaps (push) Successful in 1m35s
Two upstream-parity keymap fixes (confirmed against upstream
ftplugin/vimwiki.vim):

1. <Leader>w<Leader>t collision — nuwiki bound both <Leader>w<Leader>t and
   <Leader>w<Leader>m to tomorrow's diary. Upstream: <Leader>w<Leader>t opens
   today's diary in a NEW TAB, <Leader>w<Leader>m opens tomorrow. <Leader>w
   <Leader>t now calls diary_today_tab; <Leader>w<Leader>m stays tomorrow.

2. <M-CR> badd-link — adding a link target to the buffer list was mouse-only
   (<MiddleMouse>) / command-only (:VimwikiBaddLink). Upstream binds
   <M-CR> -> VimwikiBaddLink. Added normal-mode <M-CR> -> badd_link to the
   links group of both clients.

Both clients (lua/nuwiki/keymaps.lua, ftplugin/vimwiki.vim); README + doc/
nuwiki.txt updated. Tests: map[n].<M-CR> in both harnesses;
diary.leader_t_opens_today_in_tab / diary.leader_m_opens_tomorrow (vim).
nvim 270, vim 263+18, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 16:21:49 +00:00
gffranco 9de8543385 fix(client): colour-span conceal must skip unallocatable colours
CI / cargo fmt --check (push) Successful in 34s
CI / cargo clippy (push) Successful in 42s
CI / cargo test (push) Successful in 35s
CI / editor keymaps (push) Successful in 1m36s
A literal `<span style="color:…">` in prose (the sample wiki's own colorize
instructions used one, with a `…` ellipsis as the colour) was matched by the
scanner and fed to `highlight guifg=…`, which raised E254 on the un-silenced
guifg line. That aborted the whole nuwiki#colors#refresh(), so on the Vim
clients NO spans got concealed (start-vim) and follow-link crashed mid
FileType autocmd (start-vim-coc). Neovim happened to dodge it depending on
which buffer was scanned.

s:define() now:
- validates the colour (only #hex or an alphabetic name) and skips anything
  else — rgb()/hsl() functions and prose examples no longer create bogus
  conceal regions or errors;
- runs both `highlight` calls under `silent!`, so a valid-format but unknown
  name can't abort the refresh either (tags still conceal, text just isn't
  recoloured).

Also reworded the sample wiki's colorize note so it no longer embeds a
literal span tag.

Test: colorize.skips_unallocatable_colour (vim) — an rgb() span before a real
one: refresh doesn't error, the rgb span isn't concealed, the real span still
is. nvim 269, vim 260+18, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 16:09:15 +00:00
gffranco 15ba774a28 feat(client): conceal colour spans down to their coloured text
CI / cargo fmt --check (push) Successful in 25s
CI / cargo clippy (push) Successful in 37s
CI / cargo test (push) Successful in 37s
CI / editor keymaps (push) Successful in 1m48s
A :VimwikiColorize'd word showed the literal
`<span style="color:NAME">TEXT</span>` markup. Now the tags are concealed
and TEXT is painted in NAME, so the buffer shows just the coloured word —
matching the HTML export.

New autoload/nuwiki/colors.vim: nuwiki#colors#refresh() scans the buffer
and, per distinct colour, defines a syntax region that conceals the
`<span …>` / `</span>` tags (concealends) and highlights the body with the
span's actual colour (guifg always; ctermfg for named colours). Idempotent
(clears the group before redefining) and tracked in b:nuwiki_color_seen.

Refresh is driven from three places so it's both correct and immediate:
- syntax/vimwiki.vim: initial pass + re-establish after :colorscheme reload
  (resets the per-buffer cache since :syntax clear drops the regions);
- ftplugin TextChanged/InsertLeave autocmd for spans that arrive via paste/
  undo/external edits;
- colorize() itself calls refresh() right after wrapping, so a freshly
  colorized word conceals instantly (TextChanged doesn't fire reliably mid
  command / in headless ex-mode).

The LSP @vimwikiColor token no longer links to Constant, so in Neovim it
doesn't override the real per-span colour on the concealed text. Pure syntax
+ :highlight — works identically in Vim, coc.nvim, and Neovim, no LSP needed.

Tests: colorize.conceal_hides_tags_shows_text (both harnesses) and
colorize.command_conceals_immediately (vim). Sample wiki's colorize section
notes the conceal. nvim 269, vim 259+18, config-parity green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 16:01:21 +00:00
gffranco 2facb40265 fix(client): VimwikiColorize accepts a range (no more E481 on selection)
CI / cargo fmt --check (push) Successful in 31s
CI / cargo clippy (push) Successful in 24s
CI / cargo test (push) Successful in 39s
CI / editor keymaps (push) Successful in 1m31s
Selecting text and running :VimwikiColorize {color} raised
"E481: No range allowed" — Vim prepends '<,'> to the command when invoked
from a visual selection, but the command was defined without -range.

All four colorize command defs (Vim + Neovim, Vimwiki* + Nuwiki*) are now
-range and forward the range count to the handler. A ranged (visual)
invocation wraps the '< / '> selection; a bare invocation wraps the cword.
The x-mode <Leader>wc mapping passes the visual flag explicitly.

The Vim-branch colorize() gained selection support (it was cword-only),
matching the Neovim branch, so both clients wrap a visual selection
identically. visual_selection_range() (Lua) no longer gates on
vim.fn.visualmode() — the explicit visual flag now carries that intent, and
the marks check guards unset selections.

Tests: cmd.Colorize_range_wraps_selection (nvim) and
colorize.{command_wraps_cword,visual_wraps_selection,ranged_command_no_error}
(vim). nvim 268, vim 257+18, all green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:37:09 +00:00
gffranco 6983daa637 fix(follow-link): resolve+open definitions ourselves on the Vim clients
CI / cargo fmt --check (push) Successful in 16s
CI / cargo clippy (push) Successful in 21s
CI / cargo test (push) Successful in 32s
CI / editor keymaps (push) Successful in 1m39s
The Vim follow-link path delegated to the LSP client's jump UI
(:LspDefinition / coc jumpDefinition), which broke two ways for wiki
link-following:

1. **No create-on-follow (vim-lsp + coc).** vim-lsp's location handler
   readfile()s the target to build a quickfix entry; for a not-yet-created
   page that throws E484 and aborts the jump, so <CR> on [[NewPage]] did
   nothing. The server was correct throughout — textDocument/definition
   returns a *synthesised* location for missing pages (verified over
   JSON-RPC).
2. **Wrong window placement (coc).** Without an explicit open command coc
   fell back to coc.preferences.jumpCommand (e.g. a tab command).

Stop delegating: nuwiki#commands#follow_link_or_create() /
follow_link_drop() now resolve textDocument/definition directly and open
the URI themselves via a shared s:open_definition(open_cmd) helper — :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. Removes
s:jump_definition / s:drop_from_response.

Also fix the coc action name: CocAction('getDefinition') does not exist
(E605 "Action getDefinition does not exist") — the registered action is
'definitions'. Fixed in s:open_definition and badd_link.

coc config delivery: the setup guidance shipped without
initializationOptions, so coc users never sent wiki_root and the server
resolved links against its default root (existing pages flagged broken,
follow-to-create landed in the cwd). The printed snippet
(autoload/nuwiki/lsp.vim) now emits initializationOptions populated with
the resolved settings, and the README coc snippet documents it as required.

Add development/start-vim-coc.sh — a coc.nvim dev launcher (sibling of
start-vim.sh) that wires coc's prebuilt release branch + a generated
coc-settings.json (with initializationOptions), deliberately omitting
vim-lsp so the coc path is exercised; doubles as a reproducer.

Tests: new cr.follow_opens_missing_page_in_current_window case in
test-keymaps-vim.vim (stubs CocAction to a missing page, asserts
current-window :edit). Keymap suite 254+18 green; config-parity (Vim +
Neovim) green. Neovim path unchanged and re-confirmed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 15:01:14 +00:00
gffranco cca2043294 test(client): cover bare gl/gL remove-checkbox + command-driven remove-done
Swap the gl<Space>/gL<Space> surface assertions for bare gl/gL; add behavioral
cases for gl (item) and gL (whole list) remove-checkbox, and drive remove-done
through :NuwikiRemoveDone / :NuwikiRemoveDone! now that it is command-only.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 08:41:27 -03:00
gffranco 8a99765e02 test(client): assert gl/gL list change-symbol mappings
Add the 16 gl<sym>/gL<sym> keys to the lists mapping_surface in both
keymap harnesses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 08:10:10 -03:00
gffranco 82b6bc9c60 test(client): cover Vim/Neovim link-follow command surface + tab-drop
Add SplitLink/VSplitLink/TabnewLink/TabDropLink/GoBackLink to both
keymap harness command lists, plus a smoke check that
nuwiki.commands.follow_link_drop is callable.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-31 07:54:25 -03:00
gffranco 63ef1b59a2 docs(parity): document new commands and extend keymap harness coverage
CI / cargo fmt --check (push) Successful in 27s
CI / cargo clippy (push) Successful in 44s
CI / cargo test (push) Successful in 47s
CI / editor keymaps (push) Successful in 1m30s
Update the README command tables for the full :Nuwiki*/:Vimwiki* surface
and add command-registration assertions (removeCheckbox, catUrl, and the
other parity entry points) to both the Vim and Neovim keymap harnesses.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 17:36:05 -03:00
gffranco 8ab6015405 Major clean up and improvements to vimwiki compatibility and documentation.
CI / cargo fmt --check (push) Successful in 33s
CI / cargo clippy (push) Successful in 23s
CI / cargo test (push) Successful in 33s
CI / editor keymaps (push) Successful in 1m25s
Reviewed-on: #1
2026-05-30 18:35:40 +00:00