feat(client): conceal colour spans down to their coloured text
A :VimwikiColorize'd word showed the literal `<span style="color:NAME">TEXT</span>` markup. Now the tags are concealed and TEXT is painted in NAME, so the buffer shows just the coloured word — matching the HTML export. New autoload/nuwiki/colors.vim: nuwiki#colors#refresh() scans the buffer and, per distinct colour, defines a syntax region that conceals the `<span …>` / `</span>` tags (concealends) and highlights the body with the span's actual colour (guifg always; ctermfg for named colours). Idempotent (clears the group before redefining) and tracked in b:nuwiki_color_seen. Refresh is driven from three places so it's both correct and immediate: - syntax/vimwiki.vim: initial pass + re-establish after :colorscheme reload (resets the per-buffer cache since :syntax clear drops the regions); - ftplugin TextChanged/InsertLeave autocmd for spans that arrive via paste/ undo/external edits; - colorize() itself calls refresh() right after wrapping, so a freshly colorized word conceals instantly (TextChanged doesn't fire reliably mid command / in headless ex-mode). The LSP @vimwikiColor token no longer links to Constant, so in Neovim it doesn't override the real per-span colour on the concealed text. Pure syntax + :highlight — works identically in Vim, coc.nvim, and Neovim, no LSP needed. Tests: colorize.conceal_hides_tags_shows_text (both harnesses) and colorize.command_conceals_immediately (vim). Sample wiki's colorize section notes the conceal. nvim 269, vim 259+18, config-parity green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
" autoload/nuwiki/colors.vim — conceal colour spans down to their text.
|
||||
"
|
||||
" `:VimwikiColorize NAME` wraps text in `<span style="color:NAME">TEXT</span>`.
|
||||
" This hides the two tags (conceal) and paints TEXT in NAME, so the buffer
|
||||
" shows just the coloured word — matching how the HTML export renders it.
|
||||
"
|
||||
" Pure syntax + `:highlight`, no LSP needed, so it works the same in Vim,
|
||||
" coc.nvim, and Neovim. New colours appear as the user runs :VimwikiColorize,
|
||||
" so the ftplugin re-runs refresh() on text changes; we track which colours
|
||||
" already have a syntax group in b:nuwiki_color_seen to stay idempotent.
|
||||
|
||||
" Scan the buffer for `<span style="color:…">` and define a concealing,
|
||||
" colouring syntax region for each colour not yet seen.
|
||||
function! nuwiki#colors#refresh() abort
|
||||
if !exists('b:nuwiki_color_seen')
|
||||
let b:nuwiki_color_seen = {}
|
||||
endif
|
||||
let l:n = line('$')
|
||||
let l:lnum = 1
|
||||
while l:lnum <= l:n
|
||||
let l:line = getline(l:lnum)
|
||||
if stridx(l:line, '<span style="color:') >= 0
|
||||
let l:pos = 0
|
||||
while 1
|
||||
let l:mp = matchstrpos(l:line, '<span style="color:[^"]\{-}">', l:pos)
|
||||
if l:mp[1] < 0
|
||||
break
|
||||
endif
|
||||
let l:pos = l:mp[2]
|
||||
call s:define(matchstr(l:mp[0], 'color:\zs[^"]\{-}\ze">'))
|
||||
endwhile
|
||||
endif
|
||||
let l:lnum += 1
|
||||
endwhile
|
||||
endfunction
|
||||
|
||||
" Define (once per colour) a region that conceals `<span …>` / `</span>` and
|
||||
" paints the wrapped text in that colour.
|
||||
function! s:define(color) abort
|
||||
if a:color ==# '' || has_key(b:nuwiki_color_seen, a:color)
|
||||
return
|
||||
endif
|
||||
let b:nuwiki_color_seen[a:color] = 1
|
||||
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.
|
||||
silent! execute 'syntax clear ' . l:grp
|
||||
" `concealends` hides the start/end matches (the tags); the region body
|
||||
" (the text) keeps the l:grp highlight. `oneline` since spans don't wrap.
|
||||
execute 'syntax region ' . l:grp
|
||||
\ . ' matchgroup=Conceal'
|
||||
\ . ' 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
|
||||
if a:color !~# '^#'
|
||||
silent! execute 'highlight ' . l:grp . ' ctermfg=' . a:color
|
||||
endif
|
||||
endfunction
|
||||
@@ -887,6 +887,7 @@ function! nuwiki#commands#colorize(...) abort
|
||||
\ . l:open_tag . strpart(l:line, l:sc - 1, l:ec - l:sc + 1) . l:close_tag
|
||||
\ . strpart(l:line, l:ec)
|
||||
call setline(l:sp[1], l:new)
|
||||
call nuwiki#colors#refresh()
|
||||
return
|
||||
endif
|
||||
endif
|
||||
@@ -912,6 +913,7 @@ function! nuwiki#commands#colorize(...) abort
|
||||
\ . l:open_tag . l:word . l:close_tag
|
||||
\ . strpart(l:line, l:right - 1)
|
||||
call setline('.', l:new)
|
||||
call nuwiki#colors#refresh()
|
||||
endfunction
|
||||
" Cluster C — link helpers.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user