From 9de8543385a4062a10d787a2ef193c3e790ad451 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Fr=C3=B3es=20Franco?= Date: Sun, 31 May 2026 16:09:15 +0000 Subject: [PATCH] fix(client): colour-span conceal must skip unallocatable colours MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A literal `` 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) --- autoload/nuwiki/colors.vim | 14 +++++++++++--- development/_common.sh | 6 +++--- development/tests/test-keymaps-vim.vim | 18 ++++++++++++++++++ 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/autoload/nuwiki/colors.vim b/autoload/nuwiki/colors.vim index fda67e3..7943d1b 100644 --- a/autoload/nuwiki/colors.vim +++ b/autoload/nuwiki/colors.vim @@ -41,6 +41,13 @@ function! s:define(color) abort return endif let b:nuwiki_color_seen[a:color] = 1 + " Only handle colours Vim can actually allocate: a #hex value or an + " alphabetic name. Anything else — rgb()/hsl() functions, or a literal + " `` that turns up in prose/examples — is skipped, so + " a stray match can't create a bogus conceal region or abort the refresh. + if a:color !~# '^#\x\{3,8}$' && a:color !~# '^[A-Za-z][A-Za-z0-9]*$' + return + endif let l:grp = 'nuwikiColorSpan_' . substitute(a:color, '[^A-Za-z0-9]', '_', 'g') let l:esc = escape(a:color, '/\.*$^~[]') " Clear first so re-runs / load-order never stack duplicate regions. @@ -52,9 +59,10 @@ function! s:define(color) abort \ . ' start=//' \ . ' end=##' \ . ' oneline keepend concealends' - " guifg works for names and #hex under 'termguicolors'. ctermfg only accepts - " named colours, so try it for non-hex and swallow E254 for unknown names. - execute 'highlight default ' . l:grp . ' guifg=' . a:color + " guifg works for names and #hex under 'termguicolors'; ctermfg only for + " named colours. Both are best-effort — `silent!` swallows E254 for a name + " Vim doesn't know (the tags still conceal, the text just isn't recoloured). + silent! execute 'highlight default ' . l:grp . ' guifg=' . a:color if a:color !~# '^#' silent! execute 'highlight ' . l:grp . ' ctermfg=' . a:color endif diff --git a/development/_common.sh b/development/_common.sh index 1e297e7..71b2011 100644 --- a/development/_common.sh +++ b/development/_common.sh @@ -97,9 +97,9 @@ super^script^ and sub,,script,,, and inline math $e^{i\pi} + 1 = 0$. Put the cursor on a word and run `:VimwikiColorize red` (or press `wc` and type a colour); or visually select a phrase and press -`wc`. Each wraps the target in `` — -the tags are concealed, so you see just the word painted in that colour -(move the cursor onto it to reveal the raw markup). +`wc`. Each wraps the target in an inline colour-span tag whose +markup is concealed, so you see just the word painted in that colour (move +the cursor onto it to reveal the raw markup). - colorize this important word - now select and colour this whole phrase diff --git a/development/tests/test-keymaps-vim.vim b/development/tests/test-keymaps-vim.vim index ef9baeb..45c299d 100644 --- a/development/tests/test-keymaps-vim.vim +++ b/development/tests/test-keymaps-vim.vim @@ -545,6 +545,24 @@ call s:record( \ 'concealed=' . synconcealed(1, 1)[0] \ . ' grp=' . synIDattr(synID(1, stridx(s:cz_l2, 'target') + 1, 1), 'name')) +" A span whose colour Vim can't allocate (rgb()/prose) must be skipped — not +" abort refresh, not conceal — while a real span afterwards still conceals. +call s:set_buf(['plain', 'x y z', 'word z']) +call cursor(1, 1) +let s:cz_e = '' +try + call nuwiki#colors#refresh() +catch + let s:cz_e = v:exception +endtry +call s:record( + \ s:cz_e ==# '' + \ && synconcealed(3, 1)[0] == 1 + \ && synconcealed(2, stridx(getline(2), '