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), '