I like to have my neovim to bold the language keywords, italicize the comments, or both italicize and bold all the builtin functions, type or constants etc. And I want this to be consistent across colorschemes.
In vim/neovim, to update a highlight group it is as simple as highlight HighlightGroupToModified gui=bold,italic,underline
.
But this is problematic if the HighlightGroupToModified
is defined as a link to other highlight group.
For example highlight TSInclude
might be linked to Include
by your colorscheme, so executing hi TSInclude gui=bold
will apply bold to TSInclude but wipe out any foreground and background color information that was originally defined by linking to Include
highlight group.
Since every colorschemes can arbitrarily choose to define a highlight group explicitly or by linking, adding hi TSConstant gui=bold
to your config are bound to break when you switch colorschemes.
A manual approach is to recursively go down the linking chain defined by colorscheme, e.g TSConstant
links to Constant
links to PreProc
, and apply your edit to PreProc
If you like to switch colorscheme often, or have a different colorscheme for different remote hosts, it is really annoying to manually inspect all the highlight groups you would like to modified for your colorscheme.
In neovim, you can directly get the highlight group definition irrespective of the link by using vim.api.nvim_get_by_name
.
Then you can set the highlight group using vim.api.nvim_set_hl
.
You can combine it together to have a function that will update any highlight group you like, without caring if it was defined by link or not:
local function mod_hl(hl_name, opts)
local is_ok, hl_def = pcall(vim.api.nvim_get_hl_by_name, hl_name, true)
if is_ok then
for k,v in pairs(opts) do hl_def[k] = v end
vim.api.nvim_set_hl(0, hl_name, hl_def)
end
end
The pcall
is for protected call, in case when you execute this function the highlight group has not yet been defined because of some lazyloading.
You can use it by calling `mod_hl("TSConstant", {bold=true, italic=false}).
Now it doesn't matter if TSConstant was defined by link or not, if it was already italicize or not, you know your TSConstant will be bold and not italic, with the color still defined by your colorscheme.
Now you can define a autocommand to execute a bunch of the function call everytime you change colorscheme like:
-- Execute on VimEnter too because somehow on startup TS... is not defined even after executing colorscheme command
vim.api.nvim_create_autocmd({"VimEnter", "ColorScheme"}, {
group = vim.api.nvim_create_augroup('Color', {}),
pattern = "*",
callback = function ()
mod_hl("TSInclude", { bold=true, italic=true })
mod_hl("TSKeywordReturn", { bold=true, italic=true })
mod_hl("TSConstBuiltin", { bold=true, italic=true })
.........
})
Before:
After:
Full config:
-- Due to the way different colorschemes configure different highlights group,
-- there is no universal way to add gui options to all the desired components.
-- Findout the final highlight group being linked to and update gui option.
local function mod_hl(hl_name, opts)
local is_ok, hl_def = pcall(vim.api.nvim_get_hl_by_name, hl_name, true)
if is_ok then
for k,v in pairs(opts) do hl_def[k] = v end
vim.api.nvim_set_hl(0, hl_name, hl_def)
end
end
vim.api.nvim_create_autocmd({"VimEnter", "ColorScheme"}, {
group = vim.api.nvim_create_augroup('Color', {}),
pattern = "*",
callback = function ()
mod_hl("TSKeywordReturn", { bold=true, italic=true })
mod_hl("TSConstBuiltin", { bold=true, italic=true })
mod_hl("TSFuncBuiltin", { bold=true, italic=true })
mod_hl("TSTypeBuiltin", { bold=true, italic=true })
mod_hl("TSBoolean", { bold=true, italic=true })
mod_hl("TSType", { bold=true })
mod_hl("TSConstructor", { bold=true })
mod_hl("TSOperator", { bold=true })
mod_hl("TSInclude", { italic=true, })
mod_hl("TSVariableBuiltin",{ italic=true })
mod_hl("TSConditional", { italic=true })
mod_hl("TSKeyword", { italic=true })
mod_hl("TSKeywordFunction", { italic=true })
mod_hl("TSComment", { italic=true })
mod_hl("TSParameter", { italic=true })
mod_hl("semshiBuiltin", { italic=true, })
-- vim.api.nvim_set_hl(0, "semshiImported", {link="TSConstant"})
-- mod_hl("semshiImported", { bold=true, })
vim.api.nvim_set_hl(0, "semshiAttribute", {link="TSAttribute"})
-- mod_hl("TSVariable", { bold=false, italic=false, })
-- mod_hl("Folded", { bg="" })
end
})
vim.cmd "set termguicolors"
vim.cmd "colorscheme catppuccin"