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>
This commit is contained in:
2026-05-31 15:37:09 +00:00
parent 279dacff7a
commit 2facb40265
6 changed files with 98 additions and 14 deletions
+38
View File
@@ -477,6 +477,44 @@ call s:record(
\ 'ext=' . get(get(s:wl, 1, {}), 'ext', ''))
unlet g:nuwiki_wikis
" ===== Colorize (cword, visual selection, ranged command) =====
" The command is -nargs=1 -range: normal invocation wraps the cword; a visual
" range (`:'<,'>VimwikiColorize` / the x-mode <Leader>wc map) wraps the
" selection. Run these while still on the vimwiki buffer (the buffer-local
" command must be defined).
call s:set_buf(['word here'])
call cursor(1, 1)
silent VimwikiColorize red
call s:record(
\ getline(1) ==# '<span style="color:red">word</span> here' ? 1 : 0,
\ 'colorize.command_wraps_cword',
\ 'got ' . string(getline(1)))
" Visual selection → wraps the selection (visual flag passed explicitly).
call s:set_buf(['one two three'])
call cursor(1, 5)
call feedkeys("viw\<Esc>", 'tx')
call nuwiki#commands#colorize('blue', 2)
call s:record(
\ getline(1) ==# 'one <span style="color:blue">two</span> three' ? 1 : 0,
\ 'colorize.visual_wraps_selection',
\ 'got ' . string(getline(1)))
" Ranged command must not raise E481 and wraps the selection.
call s:set_buf(['alpha beta gamma'])
call cursor(1, 8)
call feedkeys("viw\<Esc>", 'tx')
let s:cz_err = ''
try
silent '<,'>VimwikiColorize green
catch
let s:cz_err = v:exception
endtry
call s:record(
\ s:cz_err ==# '' && getline(1) ==# 'alpha <span style="color:green">beta</span> gamma' ? 1 : 0,
\ 'colorize.ranged_command_no_error',
\ 'err=' . s:cz_err . ' got ' . string(getline(1)))
" ===== Follow-link resolves + opens in the current window (regression) =====
" follow_link_or_create() must resolve the definition itself and `:edit` the
" target in the CURRENT window — including a page that does not exist yet
+12
View File
@@ -761,6 +761,18 @@ vim.defer_fn(function()
error('visual colorize did not wrap selection: ' .. got)
end
end)
-- Invoking the command with a range (`:'<,'>VimwikiColorize`, as Vim builds
-- it when you select then type the command) must not error (-range) and
-- wraps the selection.
tobj_case('cmd.Colorize_range_wraps_selection', function()
set_buf({ 'pick this word' })
vim.cmd('normal! 0wviw\27') -- select 'this'
vim.cmd("'<,'>VimwikiColorize orange")
local got = vim.api.nvim_get_current_line()
if got ~= 'pick <span style="color:orange">this</span> word' then
error('ranged command did not wrap selection: ' .. got)
end
end)
-- ===== Wiki picker (config-driven, no LSP) =====
-- The picker must build its list from config so it works from any buffer
+11 -5
View File
@@ -129,11 +129,17 @@ fix site.
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`.
`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`.
- [ ] **`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