1

I can read a value from an option like:

let b = &background

Is there a way to read a value from a highlight group? Something like this pseudo-code:

let b = &StatusLine['ctermbg']

Ultimately, what I want to do is define a new highlight group in terms of other highlight group colors (not a link, but picking specific values from more than one highlight group, namely StatusLine and StatusLineNC in my case)

4

As far as I know, there's not a simple way to do this. Here's a function that should be able to return the value given the highlight group and term. If there is no such term, an empty string will be returned instead.

function! ReturnHighlightTerm(group, term)
   " Store output of group to variable
   let output = execute('hi ' . a:group)

   " Find the term we're looking for
   return matchstr(output, a:term.'=\zs\S*')
endfunction

Given this function you should be able to do

let b = ReturnHighlightTerm('StatusLine', 'ctermbg')

to get what you want.

See :help execute(), :help :highlight, and :help matchstr() for more info on how this works.

  • 1
    Using the execute() function is better than :redir, e.g. let l:output = execute('hi ' . a:group). See here for a very similar example with :syntax list. Aside from being more readable, I've found that redir has some serious issues in some cases. I forgot what it was exactly since it was a while ago, but I believe it had to do with nesting two redirs in some complicated ways with plugins/autocommands which causes the wrong output to end up in the wrong variable (!!!!) Suffice to say, I haven't used redir since. – Martin Tournoij May 3 '17 at 23:23
  • Ah, cool! I didn't know about execute(). Thanks! – Tumbler41 May 4 '17 at 4:12
  • @Carpetsmoker I believe that problem is not solved by using execute(). I think execute() suffers from the same problem. – Christian Brabandt May 4 '17 at 12:54
  • Ow, I didn't know that @ChristianBrabandt :-( I haven't had any problems since I replaced redir with execute(), though; but perhaps that's just coincidence. – Martin Tournoij May 4 '17 at 12:59
  • @Carpetsmoker @ChristianBrabandt at least the execute() solution is simpler and reads better, so I'd stick with it... – ericbn May 4 '17 at 13:43
2

I ended up writing a generic function that turns a highlight group into a dictionary of {key}={arg} pairs. Leaving it here for future reference:

function! GetHighlight(group)
  let output = execute('hi ' . a:group)
  let list = split(output, '\s\+')
  let dict = {}
  for item in list
    if match(item, '=') > 0
      let splited = split(item, '=')
      let dict[splited[0]] = splited[1]
    endif
  endfor
  return dict
endfunction

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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