fix(client): colour-span conceal must skip unallocatable colours
CI / cargo fmt --check (push) Successful in 34s
CI / cargo clippy (push) Successful in 42s
CI / cargo test (push) Successful in 35s
CI / editor keymaps (push) Successful in 1m36s

A literal `<span style="color:…">` 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) <noreply@anthropic.com>
This commit is contained in:
2026-05-31 16:09:15 +00:00
parent 15ba774a28
commit 9de8543385
3 changed files with 32 additions and 6 deletions
+11 -3
View File
@@ -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
" `<span style="color:…">` 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=/<span style="color:' . l:esc . '">/'
\ . ' end=#</span>#'
\ . ' 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