feat(13.1): colorize + color_dic → ColorNode renderer
Closes the last pending §13.1 entries: - **`nuwiki.colorize`** (client-side, Lua + VimL) — wraps the word at cursor (or the visual selection on Neovim) in an inline `<span style="color:%c">…</span>` template. Matches vimwiki's default `color_tag_template`. Bound to `<Leader>wc` in both normal and visual mode on both editor paths; the previous "deferred" stub is gone. - **`color_dic` → renderer** — `HtmlConfig` gains a `color_dic: HashMap<String, String>` field reading the same key out of `initializationOptions` / `didChangeConfiguration`. The HTML export path threads it into `HtmlRenderer::with_colors`; `ColorNode` now picks `style="color:<value>"` when the colour name is in the dict, falling back to the existing `class="color-<name>"` when it isn't. SPEC §13.1 is fully checked off — the table moved from "deferred sketch" to a per-command status table marking all 11 commands done, plus a note on the `color_dic` follow-up landing alongside. README's "Phase 14 list & table edit commands" row now reads ✅ without the deferred-subset caveat, and the §13.1-blocked text-objects note in the keymaps section is rephrased as "planned follow-ups". Tests: 4 new in `phase17_colorize.rs` covering the renderer fallback when the dict is empty, the inline-style emission for a listed name, the fallback path for an unlisted name in a populated dict, and the `initializationOptions` JSON shape. Total 414 Rust tests pass; clippy clean; keymap harness still 20/20. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
+55
-1
@@ -501,7 +501,61 @@ function M.table_move_column_right()
|
||||
exec('nuwiki.table.moveColumn', { p })
|
||||
end
|
||||
|
||||
M.colorize = _not_yet(':VimwikiColorize')
|
||||
--- `:VimwikiColorize {color}` — wrap the word (or visual selection)
|
||||
--- under cursor in an inline span tag. Matches vimwiki's behaviour:
|
||||
--- the template is `<span style="color:%c">%s</span>` with `%c`
|
||||
--- replaced by the user-supplied colour and `%s` by the wrapped text.
|
||||
--- Pure-Lua; no server roundtrip needed.
|
||||
local function visual_selection_range()
|
||||
local mode = vim.fn.visualmode()
|
||||
if mode == '' then return nil end
|
||||
local s = vim.api.nvim_buf_get_mark(0, '<')
|
||||
local e = vim.api.nvim_buf_get_mark(0, '>')
|
||||
if s[1] == 0 or e[1] == 0 then return nil end
|
||||
return s[1], s[2], e[1], e[2]
|
||||
end
|
||||
|
||||
function M.colorize(color)
|
||||
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
|
||||
end
|
||||
-- Fall back to the cword.
|
||||
local cword = vim.fn.expand('<cword>')
|
||||
if cword == '' then return end
|
||||
local col = vim.api.nvim_win_get_cursor(0)[2]
|
||||
local left = col
|
||||
while left > 0 and line:sub(left, left):match('[%w_%-]') do
|
||||
left = left - 1
|
||||
end
|
||||
if not line:sub(left + 1, left + 1):match('[%w_%-]') then
|
||||
left = left + 1
|
||||
end
|
||||
local right = left + 1
|
||||
while right <= #line and line:sub(right, right):match('[%w_%-]') do
|
||||
right = right + 1
|
||||
end
|
||||
local before = line:sub(1, left)
|
||||
local word = line:sub(left + 1, right - 1)
|
||||
local after = line:sub(right)
|
||||
local new_line = before .. open_tag .. word .. close_tag .. after
|
||||
vim.api.nvim_buf_set_lines(0, row - 1, row, false, { new_line })
|
||||
end
|
||||
|
||||
-- §13.1 Cluster C — link helpers.
|
||||
|
||||
|
||||
@@ -189,8 +189,10 @@ function M.attach(bufnr, mappings)
|
||||
map('n', '<Leader>wn', cmd.wiki_goto_page, { desc = 'nuwiki: goto page' }, bufnr)
|
||||
map('n', '<Leader>wd', cmd.delete_file, { desc = 'nuwiki: delete page' }, bufnr)
|
||||
map('n', '<Leader>wr', cmd.rename_file, { desc = 'nuwiki: rename page' }, bufnr)
|
||||
map('n', '<Leader>wc', deferred(':VimwikiColorize'), { desc = 'nuwiki: colorize (deferred)' }, bufnr)
|
||||
map('x', '<Leader>wc', deferred(':VimwikiColorize'), { desc = 'nuwiki: colorize (deferred)' }, 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,
|
||||
{ desc = 'nuwiki: wrap selection in colour span' }, bufnr)
|
||||
end
|
||||
|
||||
-- ===== Diary nav =====
|
||||
|
||||
Reference in New Issue
Block a user