3

I would like to create a new highlighting group that is exactly like an existing one except for one (or more) properties. For example, the new group could be an underlined version of the existing one.

Context: I'm using coc.nvim and its semantic highlighting feature. To support the language server protocol's token modifiers, coc.nvim creates combined highlighting groups. For example, CocSemVariable for immutable variables, and CocSemMutableVariable for mutable ones. What I would like to do is something like this:

highlight! link CocSemMutableVariable CocSemVariable
highlight! CocSemMutableVariable cterm=underline gui=underline

This doesn't work however since any highlight command will break links. Is there a way to achieve what I want?

1

1 Answer 1

3

There's no way to do this directly with highlight! since links and groups are fundamentally different. You can have a highlight that is a link or a highlight with properties, you can't have both.

Instead you can try to use hlget and hlset as follows:

let resolve = v:true   " set to v:false if not wanting to resolve links

let hl = hlget('CocSemVariable', resolve)[0]
let hl.name = 'CocSemMutableVariable'
let hl.cterm = {'underline': v:true}
let hl.gui = {'underline': v:true}
call hlset([hl])

Of course, this is not a real link and vim is not blending anything. If you modify CocSemVariable, these changes will not appear in CocSemMutableVariable. You can mitigate this to some extent via

function! Tweaks()
   ... code from above ...
endfunction
au ColorScheme * call Tweaks()

So that when groups are changed through changing colorschemes (the usual situation), the dependent groups are automatically updated.

4
  • Thanks, this could do what I want! hlget and hlset seem to be quite recent, however, and my Vim doesn't have the required patch yet. I will try to install a newer version tomorrow.
    – mtvec
    Commented Jan 23, 2022 at 21:54
  • One question: does this work if CocSemVariable is itself a link? Or would I need to follow the link(s) manually somehow?
    – mtvec
    Commented Jan 23, 2022 at 21:58
  • I just updated the answer, there's an argument to hlget that will work if it is a link. Also if you don't have hlget, you could theoretically do this with e.g., synIDattr(synIDtrans(hlID('CocSemVariable')), 'fg', 'gui') but it is a lot more effort.
    – Mass
    Commented Jan 23, 2022 at 22:05
  • Thanks, I almost got this to work. The problem now seems to be that my color scheme defines the thing that CocSemVariable links to in after/syntax which seems to be called after the ColorScheme autocmd. So hlget returns a cleared highlight group. Is there another place to call Tweak to ensure it always comes last?
    – mtvec
    Commented Jan 27, 2022 at 12:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.