feat(commands): ChangeSymbolTo -range, GenerateLinks path filter, NuwikiGenerateTags
CI / cargo fmt --check (push) Successful in 29s
CI / cargo clippy (push) Successful in 34s
CI / cargo test (push) Successful in 45s
CI / editor keymaps (push) Failing after 1m43s

Closes the three new command gaps from the 2026-05-31 re-audit (all real,
client-side, both clients × Vimwiki/Nuwiki):

- VimwikiChangeSymbolTo / ListChangeSymbolI / NuwikiChangeSymbol are now
  -range -nargs=1 via a new list_change_symbol_range(symbol,l1,l2) helper that
  loops over_range; was -nargs=1 only → E481 on a visual selection.
  ChangeSymbolInListTo/InList stay range-less.
  Bonus: the Neovim VimwikiChangeSymbolInListTo + NuwikiChangeSymbolInList defs
  passed whole_list=false, changing only the current item — corrected to true.

- VimwikiGenerateLinks / NuwikiGenerateLinks are now -nargs=?; with an arg the
  client dispatches the existing server command nuwiki.links.generateForPath
  ({path}) for real subtree-scoped link generation, else nuwiki.links.generate.
  Was bare → E488 on an arg.

- Added NuwikiGenerateTags (Vim + Neovim) mirroring VimwikiGenerateTags, with
  -nargs=? -complete=…tags — closes the :Vimwiki*↔:Nuwiki* alias asymmetry.

Tests: cmd.ChangeSymbolTo_range_sets_marker, cmd.GenerateLinks_accepts_optional_path,
cmd.NuwikiGenerateTags_exists (test-keymaps.lua, 283 pass) +
cmd.VimwikiChangeSymbolTo_accepts_range, cmd.VimwikiGenerateLinks_accepts_path,
cmd.NuwikiGenerateTags_exists (test-keymaps-vim.vim, 272/18/21). fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 21:48:31 +00:00
parent 773bbdb6a6
commit f616915581
5 changed files with 105 additions and 27 deletions
+17 -1
View File
@@ -590,8 +590,17 @@ endfunction
function! nuwiki#commands#toc_generate() abort
call s:exec('nuwiki.toc.generate', [{'uri': s:buf_uri()}])
endfunction
function! nuwiki#commands#links_generate() abort
" `:VimwikiGenerateLinks [rel_path]` — with no arg, list every page; with a
" rel-path arg, scope the generated links to that subtree (server-side
" `generateForPath`). Matches upstream's optional path argument.
function! nuwiki#commands#links_generate(...) abort
let l:path = a:0 >= 1 ? a:1 : ''
if l:path !=# ''
call s:exec('nuwiki.links.generateForPath',
\ [{'uri': s:buf_uri(), 'path': l:path}])
else
call s:exec('nuwiki.links.generate', [{'uri': s:buf_uri()}])
endif
endfunction
function! nuwiki#commands#check_links(...) abort
" a:1 = range count; when >0, restrict the report to the current buffer's
@@ -789,6 +798,13 @@ function! nuwiki#commands#list_change_symbol(symbol, whole_list) abort
call s:exec('nuwiki.list.changeSymbol', l:args)
endfunction
" `:[range]VimwikiChangeSymbolTo {sym}` / `:[range]VimwikiListChangeSymbolI {sym}`
" — upstream is `-range -nargs=1`; a range sets the marker on every list item in
" the selection (single-item when no range, since line1==line2==cursor line).
function! nuwiki#commands#list_change_symbol_range(symbol, l1, l2) abort
call s:over_range(a:l1, a:l2, { -> nuwiki#commands#list_change_symbol(a:symbol, 0) })
endfunction
function! nuwiki#commands#list_change_level(delta, whole_subtree) abort
let l:p = s:cursor_position()
let l:args = [{
+33
View File
@@ -873,6 +873,39 @@ vim.defer_fn(function()
.. vim.inspect(vim.api.nvim_buf_get_lines(0, 0, -1, false)))
end
end)
-- `:[range]VimwikiChangeSymbolTo {sym}` — now -range -nargs=1. A 1,3 range
-- must set every item's marker to the given symbol.
tobj_case('cmd.ChangeSymbolTo_range_sets_marker', function()
set_buf({ '- a', '- b', '- c' })
vim.cmd('1,3VimwikiChangeSymbolTo *')
local done = vim.wait(2000, function()
local l = vim.api.nvim_buf_get_lines(0, 0, -1, false)
for _, ln in ipairs(l) do
if not ln:match('^%*%s') then return false end
end
return true
end, 30)
if not done then
error('range change-symbol did not set all markers: '
.. vim.inspect(vim.api.nvim_buf_get_lines(0, 0, -1, false)))
end
end)
-- `:VimwikiGenerateLinks [rel_path]` — now -nargs=? (was bare; an arg raised
-- E488). Both forms must dispatch without a Vim-level command error.
tobj_case('cmd.GenerateLinks_accepts_optional_path', function()
set_buf({ '= page =' })
local ok1 = pcall(vim.cmd, 'VimwikiGenerateLinks')
local ok2 = pcall(vim.cmd, 'VimwikiGenerateLinks subdir')
if not (ok1 and ok2) then
error('GenerateLinks rejected an arg: ok1=' .. tostring(ok1) .. ' ok2=' .. tostring(ok2))
end
end)
-- :NuwikiGenerateTags alias must exist (parity with :VimwikiGenerateTags).
tobj_case('cmd.NuwikiGenerateTags_exists', function()
if vim.fn.exists(':NuwikiGenerateTags') ~= 2 then
error(':NuwikiGenerateTags not defined')
end
end)
-- `:VimwikiNormalizeLink 1` (the arg is upstream's visual flag; the command
-- is -nargs=? not -range, so no `'<,'>`) wraps the last visual selection.
tobj_case('cmd.normalize_link_visual_wraps_selection', function()
+27 -17
View File
@@ -227,23 +227,33 @@ fix site.
- [ ] `:VimwikiSearch` / `VWS` uses `lvimgrep`, not vimwiki's search engine.
_(Re-audit 2026-05-31: also `-nargs=1` in all four contexts vs upstream
`-nargs=*`.)_
- [ ] **`VimwikiChangeSymbolTo` / `VimwikiListChangeSymbolI` lack `-range`**
_(new, 2026-05-31 re-audit)_ — upstream both carry `-range -nargs=1`; nuwiki
defines them `-nargs=1` only (both branches), so `:'<,'>VimwikiChangeSymbolTo X`
over a visual selection raises `E481: No range allowed`. (Internally
consistent across nuwiki's four contexts; purely an upstream-parity gap.)
`ChangeSymbolInListTo` is correctly range-less. _Fix:_ add `-range` + a
`*_range` loop, mirroring the `ToggleListItem`/`IncrementListItem` range work.
- [ ] **`VimwikiGenerateLinks` lacks `-nargs=?`** _(new, 2026-05-31 re-audit)_
upstream takes an optional rel-path arg (`-nargs=?`); nuwiki defines it bare in
all four contexts, so `:VimwikiGenerateLinks foo` raises `E488`. Low impact
(the arg is rarely used). _Fix:_ `ftplugin/vimwiki.vim` + thread an optional
path into `links_generate`.
- [ ] **`NuwikiGenerateTags` missing** _(new, 2026-05-31 re-audit)_ — the
`:Nuwiki*` surface lacks a `GenerateTags` alias although `:VimwikiGenerateTags`
exists (both branches) and `NuwikiGenerateTagLinks` (same handler) is present.
Internal `:Vimwiki*``:Nuwiki*` asymmetry; trivial. _Fix:_ add the two
`NuwikiGenerateTags` defs (Vim + Neovim) mirroring `VimwikiGenerateTags`.
- [x] **`VimwikiChangeSymbolTo` / `VimwikiListChangeSymbolI` lack `-range`**
_(new, 2026-05-31 re-audit; fixed same day)_ — upstream both carry
`-range -nargs=1`; nuwiki had `-nargs=1` only, so a visual-range invocation
raised `E481`. _Fix:_ all four defs (Vim+Neovim × the `Vimwiki*`/`Nuwiki*`
current-item forms — `VimwikiChangeSymbolTo`/`ListChangeSymbolI` and
`NuwikiChangeSymbol`) are now `-range -nargs=1` passing `<line1>,<line2>,
<q-args>` to a new `list_change_symbol_range(symbol, l1, l2)` helper that
loops `over_range` (both clients). `ChangeSymbolInListTo`/`InList` stay
range-less. **Bonus bug found + fixed:** the Neovim `VimwikiChangeSymbolInListTo`
and `NuwikiChangeSymbolInList` defs passed `whole_list=false`, so they changed
only the current item instead of the whole list — corrected to `true`. Covered
by `cmd.ChangeSymbolTo_range_sets_marker` (`test-keymaps.lua`) +
`cmd.VimwikiChangeSymbolTo_accepts_range` (`test-keymaps-vim.vim`).
- [x] **`VimwikiGenerateLinks` lacks `-nargs=?`** _(new, 2026-05-31 re-audit;
fixed same day)_ — upstream takes an optional rel-path arg; nuwiki was bare,
so `:VimwikiGenerateLinks foo` raised `E488`. _Fix:_ all four defs are now
`-nargs=?`; `links_generate([path])` (both clients) dispatches the existing
server command `nuwiki.links.generateForPath` (with `{path}`) when an arg is
given, else `nuwiki.links.generate` — a **real** path filter, not
accepted-and-ignored (the server's `links_generate_for_path` already
implements subtree scoping). Covered by
`cmd.GenerateLinks_accepts_optional_path` (`test-keymaps.lua`) +
`cmd.VimwikiGenerateLinks_accepts_path` (`test-keymaps-vim.vim`).
- [x] **`NuwikiGenerateTags` missing** _(new, 2026-05-31 re-audit; fixed same
day)_ — added `NuwikiGenerateTags` (Vim + Neovim) mirroring
`VimwikiGenerateTags``tags_generate_links`, with `-nargs=?` +
`-complete=…tags`. Covered by `cmd.NuwikiGenerateTags_exists` (both harnesses).
- [ ] `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
+9 -7
View File
@@ -81,8 +81,8 @@ if !has('nvim')
command! -buffer VimwikiListToggle call nuwiki#commands#list_toggle_or_add_checkbox()
command! -buffer -range VimwikiIncrementListItem call nuwiki#commands#list_cycle_symbol_range(1, <line1>, <line2>)
command! -buffer -range VimwikiDecrementListItem call nuwiki#commands#list_cycle_symbol_range(-1, <line1>, <line2>)
command! -buffer -nargs=1 VimwikiChangeSymbolTo call nuwiki#commands#list_change_symbol(<q-args>, 0)
command! -buffer -nargs=1 VimwikiListChangeSymbolI call nuwiki#commands#list_change_symbol(<q-args>, 0)
command! -buffer -range -nargs=1 VimwikiChangeSymbolTo call nuwiki#commands#list_change_symbol_range(<q-args>, <line1>, <line2>)
command! -buffer -range -nargs=1 VimwikiListChangeSymbolI call nuwiki#commands#list_change_symbol_range(<q-args>, <line1>, <line2>)
command! -buffer -nargs=1 VimwikiChangeSymbolInListTo call nuwiki#commands#list_change_symbol(<q-args>, 1)
command! -buffer -bang VimwikiRemoveDone if <bang>0 | call nuwiki#commands#list_remove_done_all() | else | call nuwiki#commands#list_remove_done() | endif
command! -buffer -range VimwikiRemoveSingleCB call nuwiki#commands#list_remove_checkbox()
@@ -100,7 +100,7 @@ if !has('nvim')
command! -buffer VimwikiRss call nuwiki#commands#export_rss()
command! -buffer VimwikiTOC call nuwiki#commands#toc_generate()
command! -buffer VimwikiGenerateLinks call nuwiki#commands#links_generate()
command! -buffer -nargs=? VimwikiGenerateLinks call nuwiki#commands#links_generate(<q-args>)
command! -buffer -range VimwikiCheckLinks call nuwiki#commands#check_links(<range>, <line1>, <line2>)
command! -buffer VimwikiFindOrphans call nuwiki#commands#find_orphans()
@@ -145,12 +145,13 @@ if !has('nvim')
command! -buffer -bang NuwikiExportAll if <bang>0 | call nuwiki#commands#export_all_force() | else | call nuwiki#commands#export_all() | endif
command! -buffer NuwikiRss call nuwiki#commands#export_rss()
command! -buffer NuwikiTOC call nuwiki#commands#toc_generate()
command! -buffer NuwikiGenerateLinks call nuwiki#commands#links_generate()
command! -buffer -nargs=? NuwikiGenerateLinks call nuwiki#commands#links_generate(<q-args>)
command! -buffer -range NuwikiCheckLinks call nuwiki#commands#check_links(<range>, <line1>, <line2>)
command! -buffer NuwikiFindOrphans call nuwiki#commands#find_orphans()
command! -buffer -bang NuwikiRebuildTags call nuwiki#commands#tags_rebuild(<bang>0)
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiSearchTags call nuwiki#commands#tags_search(<q-args>)
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiGenerateTagLinks call nuwiki#commands#tags_generate_links(<q-args>)
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiGenerateTags call nuwiki#commands#tags_generate_links(<q-args>)
command! -buffer -nargs=1 -complete=customlist,nuwiki#complete#pages NuwikiGoto call nuwiki#commands#wiki_goto_page(<q-args>)
" Canonical :Nuwiki* names that mirror the documented surface.
@@ -176,7 +177,7 @@ if !has('nvim')
command! -buffer NuwikiListToggle call nuwiki#commands#list_toggle_or_add_checkbox()
command! -buffer -range NuwikiIncrementListItem call nuwiki#commands#list_cycle_symbol_range(1, <line1>, <line2>)
command! -buffer -range NuwikiDecrementListItem call nuwiki#commands#list_cycle_symbol_range(-1, <line1>, <line2>)
command! -buffer -nargs=1 NuwikiChangeSymbol call nuwiki#commands#list_change_symbol(<q-args>, 0)
command! -buffer -range -nargs=1 NuwikiChangeSymbol call nuwiki#commands#list_change_symbol_range(<q-args>, <line1>, <line2>)
command! -buffer -nargs=1 NuwikiChangeSymbolInList call nuwiki#commands#list_change_symbol(<q-args>, 1)
command! -buffer -nargs=? NuwikiNormalizeLink call nuwiki#commands#normalize_link(<args>)
command! -buffer NuwikiRenumberList call nuwiki#commands#list_renumber()
@@ -448,7 +449,7 @@ command! -buffer -bang VimwikiAll2HTML execute (<bang>0 ? "lua require('nuwi
command! -buffer VimwikiRss lua require('nuwiki.commands').export_rss()
command! -buffer VimwikiTOC lua require('nuwiki.commands').toc_generate()
command! -buffer VimwikiGenerateLinks lua require('nuwiki.commands').links_generate()
command! -buffer -nargs=? VimwikiGenerateLinks lua require('nuwiki.commands').links_generate(<q-args>)
command! -buffer -range VimwikiCheckLinks lua require('nuwiki.commands').check_links(<range>, <line1>, <line2>)
command! -buffer VimwikiFindOrphans lua require('nuwiki.commands').find_orphans()
@@ -489,12 +490,13 @@ command! -buffer NuwikiExportBrowse lua require('nuwiki.commands').
command! -buffer -bang NuwikiExportAll execute (<bang>0 ? "lua require('nuwiki.commands').export_all_force()" : "lua require('nuwiki.commands').export_all()")
command! -buffer NuwikiRss lua require('nuwiki.commands').export_rss()
command! -buffer NuwikiTOC lua require('nuwiki.commands').toc_generate()
command! -buffer NuwikiGenerateLinks lua require('nuwiki.commands').links_generate()
command! -buffer -nargs=? NuwikiGenerateLinks lua require('nuwiki.commands').links_generate(<q-args>)
command! -buffer -range NuwikiCheckLinks lua require('nuwiki.commands').check_links(<range>, <line1>, <line2>)
command! -buffer NuwikiFindOrphans lua require('nuwiki.commands').find_orphans()
command! -buffer -bang NuwikiRebuildTags lua require('nuwiki.commands').tags_rebuild('<bang>' == '!')
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiSearchTags lua require('nuwiki.commands').tags_search(<q-args>)
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiGenerateTagLinks lua require('nuwiki.commands').tags_generate_links(<q-args>)
command! -buffer -nargs=? -complete=customlist,nuwiki#complete#tags NuwikiGenerateTags lua require('nuwiki.commands').tags_generate_links(<q-args>)
command! -buffer -nargs=1 -complete=customlist,nuwiki#complete#pages NuwikiGoto lua require('nuwiki.commands').wiki_goto_page(<q-args>)
" Canonical :Nuwiki* names that mirror the documented surface.
+18 -1
View File
@@ -395,7 +395,17 @@ end
-- ===== Generation + workspace =====
M.toc_generate = function() exec('nuwiki.toc.generate', uri_args()) end
M.links_generate = function() exec('nuwiki.links.generate', uri_args()) end
-- `:VimwikiGenerateLinks [rel_path]` — optional path scopes the links to a
-- subtree via the server's generateForPath; no arg = every page.
M.links_generate = function(path)
if path and path ~= '' then
local args = uri_args()[1]
args.path = path
exec('nuwiki.links.generateForPath', { args })
else
exec('nuwiki.links.generate', uri_args())
end
end
-- range>0 restricts the report to the current buffer's [l1, l2] lines
-- (`:'<,'>VimwikiCheckLinks`); otherwise the whole workspace.
@@ -574,6 +584,13 @@ function M.list_change_symbol(symbol, whole_list)
exec('nuwiki.list.changeSymbol', { args })
end
-- `:[range]VimwikiChangeSymbolTo {sym}` / `:[range]VimwikiListChangeSymbolI {sym}`
-- — upstream is -range -nargs=1; a range sets the marker on every list item in
-- the selection (single-item when no range, since l1==l2==cursor line).
function M.list_change_symbol_range(symbol, l1, l2)
over_range(l1, l2, function() M.list_change_symbol(symbol, false) end)
end
function M.list_change_level(delta, whole_subtree)
local args = pos_args()[1]
args.delta = delta