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>
This commit is contained in:
+23
-12
@@ -960,27 +960,38 @@ local function visual_selection_range()
|
||||
return s[1], s[2], e[1], e[2]
|
||||
end
|
||||
|
||||
function M.colorize(color)
|
||||
-- colorize(color, visual): wrap text in an inline colour span.
|
||||
--
|
||||
-- `visual` MUST be passed only by the visual-mode mapping — it means "act on
|
||||
-- the `'<`/`'>` selection". We can't infer it from `vim.fn.visualmode()`,
|
||||
-- which returns the *last* visual mode used in the session (with stale marks),
|
||||
-- so the normal-mode command / mapping would otherwise wrap whatever was last
|
||||
-- selected instead of the word under the cursor.
|
||||
function M.colorize(color, visual)
|
||||
if not color or color == '' then
|
||||
color = vim.fn.input('Colour: ')
|
||||
if color == '' then return end
|
||||
end
|
||||
local sl, sc, el, ec = visual_selection_range()
|
||||
local row = vim.api.nvim_win_get_cursor(0)[1]
|
||||
local line = vim.api.nvim_get_current_line()
|
||||
local open_tag = string.format('<span style="color:%s">', color)
|
||||
local close_tag = '</span>'
|
||||
if sl and sl == el then
|
||||
-- Single-line visual selection.
|
||||
local new_line = line:sub(1, sc)
|
||||
.. open_tag
|
||||
.. line:sub(sc + 1, ec + 1)
|
||||
.. close_tag
|
||||
.. line:sub(ec + 2)
|
||||
vim.api.nvim_buf_set_lines(0, sl - 1, sl, false, { new_line })
|
||||
return
|
||||
if visual then
|
||||
local sl, sc, el, ec = visual_selection_range()
|
||||
if sl and sl == el then
|
||||
-- Single-line visual selection.
|
||||
local sline = vim.api.nvim_buf_get_lines(0, sl - 1, sl, false)[1] or ''
|
||||
local new_line = sline:sub(1, sc)
|
||||
.. open_tag
|
||||
.. sline:sub(sc + 1, ec + 1)
|
||||
.. close_tag
|
||||
.. sline:sub(ec + 2)
|
||||
vim.api.nvim_buf_set_lines(0, sl - 1, sl, false, { new_line })
|
||||
return
|
||||
end
|
||||
-- Multi-line or no usable selection: fall through to the cword.
|
||||
end
|
||||
-- Fall back to the cword.
|
||||
-- Wrap the cword.
|
||||
local cword = vim.fn.expand('<cword>')
|
||||
if cword == '' then return end
|
||||
local col = vim.api.nvim_win_get_cursor(0)[2]
|
||||
|
||||
@@ -176,7 +176,7 @@ function M.attach(bufnr, mappings)
|
||||
map('n', '<Leader>wr', cmd.rename_file, { desc = 'nuwiki: rename page' }, bufnr)
|
||||
map('n', '<Leader>wc', function() cmd.colorize() end,
|
||||
{ desc = 'nuwiki: wrap word in colour span' }, bufnr)
|
||||
map('x', '<Leader>wc', function() cmd.colorize() end,
|
||||
map('x', '<Leader>wc', function() cmd.colorize(nil, true) end,
|
||||
{ desc = 'nuwiki: wrap selection in colour span' }, bufnr)
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user