qvacua / vimr

VimR — Neovim GUI for macOS in Swift
https://twitter.com/VimRefined
MIT License
6.61k stars 218 forks source link

Themes with highlight groups using "links" to other groups do not propagate colors to SwiftUI properly #1069

Open s-daveb opened 1 month ago

s-daveb commented 1 month ago

I think I figured out why another bug where some themes do not propagate their theme colors to VimR, such as dracula.

I noticed color changes are propagated from In NvimView+Resize.swift, line 129

autocmd ColorScheme * call rpcnotify(\(channel), 'autocommand', 'colorscheme', get(nvim_get_hl(0, {'id': hlID('Normal')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('Normal')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('Visual')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('Visual')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('Directory')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('TablineSel')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('TablineSel')}), 'fg', -1))

But when I try to get those specific groups in neovim:

echo get(nvim_get_hl(0, {'id': hIID('TablineSel')}, 'fg') 
['bold': vitrue, 'cterm': {'bold': vitrue}, 'link': 'Normal'})

echo get(nvim_get_hl(0, {'id': hIID('TablineFill')}, 'fg') 
({'link': 'DraculaBgDark'})

Because some themes define highlight groups that pull their values from other groups ("link" to other groups), when using the existing code, get(nvim_get_hl(0, {'id': hlID('TablineFill')}), 'bg', -1), the result with these highlight groups is always -1.

Reading up on highlight groups in the neovim docs, they suggest using something more like synIDattr(synIDtrans(hlID('TablineFill')),'bg').

Trying it in my clients, I get:

echo synIDattr(synIDtrans(hlID('TablineFill')),'bg')
#21222c

echo synIDattr(synIDtrans(hlID('TablineFill')),'fg')

This is a lot better, returning with hex color codes starting with #, but it results in empty strings when there is no value set, which could affect how existing code handles missing color codes.

I'm working on a pull-request that changes how the colors are grabbed, without changing how their error handling ( value of -1 ) works; but I wanted to also have this issue to explain the problem.

georgeharker commented 1 month ago

I think I use a couple of plugins which do the link decode in lua. Take a look at lualine source - I think it decodes highlights to get the separators right in a highlight module. GeorgeOn May 28, 2024, at 6:36 AM, S David @.**> wrote: I think I figured out why another bug where some themes do not propagate their theme colors to VimR, such as dracula. I noticed color changes are propagated from In NvimView+Resize.swift, line 129 autocmd ColorScheme call rpcnotify((channel), 'autocommand', 'colorscheme', get(nvim_get_hl(0, {'id': hlID('Normal')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('Normal')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('Visual')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('Visual')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('Directory')}), 'fg', -1), get(nvim_get_hl(0, {'id': hlID('TablineSel')}), 'bg', -1), get(nvim_get_hl(0, {'id': hlID('TablineSel')}), 'fg', -1)) But when I try to get those specific groups in neovim: echo get(nvim_get_hl(0, {'id': hIID('TablineSel')}, 'fg') ['bold': vitrue, 'cterm': {'bold': vitrue}, 'link': 'Normal'})

echo get(nvim_get_hl(0, {'id': hIID('TablineFill')}, 'fg') ({'link': 'DraculaBgDark'}) When using the existing code, get(nvim_get_hl(0, {'id': hlID('TablineFill')}), 'bg', -1), the result with these highlight groups is always -1, becaus ethese specific groups have their values "linked" to other highlight groups. Looking at the neovim documentation, they suggest using something more like synIDattr(synIDtrans(hlID('TablineFill')),'bg'). Trying it in my clients, I get: echo synIDattr(synIDtrans(hlID('TablineFill')),'bg')

21222c

echo synIDattr(synIDtrans(hlID('TablineFill')),'fg') This is a lot better, with hex color codes starting with #, but it results in empty strings when there is no value set, which could affect how existing code handles missing color codes. I'm working on a pull-request, but I wanted to also have this issue to explain the problem.

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>

s-daveb commented 1 month ago

@georgeharker That's not a bad suggestion, but where possible, it's probably best to let the neovim runtime do all the hard work.

I found that using the builtin funtionss as such follows all links automatically:

synIDattr(synIDtrans(hlID(<GroupName>)), <fg|bg>) " -> returns '#rrggbb' or ''

I got the following vimscript function to behave like get() when the result is not found

function! GetHiColor(hlID, component)
  let color = synIDattr(synIDtrans(hlID(a:hlID)), a:component)
  if empty(color)
    return -1
  else
    return str2nr(color[1:], 16) "removes leading # and converts hex string to its int value
  endif
endfunction

echo GetHiColor('TabLineFill', 'bg')   " -> 2171436
echo get(nvim_get_hl(0, {'id': hlID('TabLineFill')}), 'bg', -1)  " -> -1

Screenshot 2024-05-28 at 2 22 56 PM