From 766a429ce71cc377bbd2680bb7b334ca9eba2857 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Sat, 19 Dec 2020 09:53:09 +0530 Subject: [PATCH] nvim: yolokai: Sync with nvim-highlite upstream --- nvim/.config/nvim/lua/yolokai.lua | 221 ++++++++++++++++++++---------- 1 file changed, 151 insertions(+), 70 deletions(-) diff --git a/nvim/.config/nvim/lua/yolokai.lua b/nvim/.config/nvim/lua/yolokai.lua index f8873f4..0d228bc 100644 --- a/nvim/.config/nvim/lua/yolokai.lua +++ b/nvim/.config/nvim/lua/yolokai.lua @@ -1,99 +1,147 @@ --[[ NOTHING INSIDE THIS FILE NEEDS TO BE EDITED BY THE USER. ]] -local yolokai = {} + +--[[ + /* + * IMPORTS + */ +--]] + local vim = vim +local api = vim.api +local exe = api.nvim_command +local fn = vim.fn --- Clear the highlighting. -vim.cmd('hi clear') - --- Disable automatic coloring for the IndentGuides plugin. -vim.g.indent_guides_auto_colors = 0 - --- If the syntax has been enabled, reset it. -if vim.fn.exists('syntax_on') then vim.cmd('syntax reset') end - --- Determine which set of colors to use. -yolokai.using_hex_or_256 = tonumber(vim.o.t_Co) >= 256 - or vim.o.termguicolors - or vim.fn.has('gui_running') - or string.find(vim.fn.expand('$TERM'), '256') - --- If we aren't using the hex and 256 colorset, then set the &t_Co variable to 16. -if not yolokai.using_hex_or_256 then vim.o.t_Co = 16 end +--[[ + /* + * VARS + */ +--]] -- These are constants for the indexes in the colors that were defined before. -local PALETTE_ANSI = 3 -local PALETTE_256 = 2 -local PALETTE_HEX = 1 -local NONE = "NONE" +local _NONE = 'NONE' +local _PALETTE_256 = 2 +local _PALETTE_ANSI = 3 +local _PALETTE_HEX = 1 +local _TYPE_STRING = 'string' +local _TYPE_TABLE = 'table' --- Get the color value of a color variable, or "NONE" as a default. -local function get(color, index) -- {{{ † - if type(color) == 'table' and color[index] then - return color[index] - elseif type(color) == 'string' then - return color - else - return NONE - end -end --}}} ‡ +-- Determine which set of colors to use. +local _USE_HEX = vim.o.termguicolors +local _USE_256 = tonumber(vim.o.t_Co) > 255 + or string.find(vim.env.TERM, '256') + +--[[ + /* + * HELPER FUNCTIONS + */ +--]] -- Add the 'blend' parameter to some highlight command, if there is one. local function blend(command, attributes) -- {{{ † if attributes.blend then -- There is a value for the `highlight-blend` field. - command[#command + 1] = ' blend='..attributes.blend + command[#command+1]=' blend='..attributes.blend + end +end --}}} ‡ + +-- filter a highlight group's style information +local function filter_group_style(value) + return value ~= 'background' + and value ~= 'blend' + and value ~= 'foreground' + and value ~= 'special' +end + +-- Get the color value of a color variable, or "NONE" as a default. +local function get(color, index) -- {{{ † + if type(color) == _TYPE_TABLE and color[index] then + return color[index] + elseif type(color) == _TYPE_STRING then + return color + else + return _NONE end end --}}} ‡ --[[ If using hex and 256-bit colors, then populate the gui* and cterm* args. If using 16-bit colors, just populate the cterm* args. ]] -local colorize = yolokai.using_hex_or_256 and function(command, attributes) -- {{{ † - command[#command + 1] = - ' ctermbg='..get(attributes.bg, PALETTE_256) - ..' ctermfg='..get(attributes.fg, PALETTE_256) - ..' guibg='..get(attributes.bg, PALETTE_HEX) - ..' guifg='..get(attributes.fg, PALETTE_HEX) - blend(command, attributes) +local colorize = _USE_HEX and function(command, attributes) -- {{{ † + command[#command+1]=' guibg='..get(attributes.bg, _PALETTE_HEX)..' guifg='..get(attributes.fg, _PALETTE_HEX) +end or _USE_256 and function(command, attributes) + command[#command+1]=' ctermbg='..get(attributes.bg, _PALETTE_256)..' ctermfg='..get(attributes.fg, _PALETTE_256) end or function(command, attributes) - command[#command + 1] = - ' ctermbg='..get(attributes.bg, PALETTE_ANSI) - ..' ctermfg='..get(attributes.fg, PALETTE_ANSI) - blend(command, attributes) + command[#command+1]=' ctermbg='..get(attributes.bg, _PALETTE_ANSI)..' ctermfg='..get(attributes.fg, _PALETTE_ANSI) end --}}} ‡ -- This function appends `selected_attributes` to the end of `highlight_cmd`. -local stylize = yolokai.using_hex_or_256 and function(command, style, color) -- {{{ † - command[#command + 1] = ' cterm='..style..' gui='..style +local stylize = _USE_HEX and function(command, style, color) + command[#command+1]=' gui='..style if color then -- There is an undercurl color. - command[#command + 1] = ' guisp='..get(color, PALETTE_HEX) + command[#command+1]=' guisp='..get(color, _PALETTE_HEX) end end or function(command, style) - command[#command + 1] = ' cterm='..style -end --}}} ‡ + command[#command+1]=' cterm='..style +end + +local function tohex(rgb) return string.format('#%06x', rgb) end + +-- Load specific &bg instructions +local function use_background_with(attributes) + return setmetatable( + attributes[vim.o.background], + {['__index'] = attributes} + ) +end + +--[[ + /* + * MODULE + */ +--]] + +local yolokai = {} + +function yolokai.group(group_name) + local no_errors, group_definition = pcall(api.nvim_get_hl_by_name, group_name, vim.o.termguicolors) + + if not no_errors then group_definition = {} end + + -- the style of the highlight group + local style = vim.tbl_filter(filter_group_style, vim.tbl_keys(group_definition)) + if group_definition.special then + style.color = tohex(group_definition.special) + end + + return { + ['fg'] = group_definition.foreground and tohex(group_definition.foreground) or _NONE, + ['bg'] = group_definition.background and tohex(group_definition.background) or _NONE, + ['blend'] = group_definition.blend, + ['style'] = style or _NONE + } +end -- Generate a `:highlight` command from a group and some attributes. function yolokai.highlight(highlight_group, attributes) -- {{{ † -- The base highlight command local highlight_cmd = {'hi! ', highlight_group} - -- Take care of special instructions for certain background colors. - if attributes[vim.o.background] then - attributes.__index = attributes - attributes = setmetatable(attributes[vim.o.background], attributes) - end - - -- Determine if there is a highlight link, and if so, assign it. - local link = (type(attributes) == 'string') and attributes or attributes.link - - if link then -- `highlight_group` is a link to another group. - highlight_cmd[3] = highlight_cmd[2]..' ' + if type(attributes) == _TYPE_STRING then -- `highlight_group` is a link to another group. + highlight_cmd[3] = highlight_cmd[2] highlight_cmd[2] = 'link ' - highlight_cmd[4] = link + highlight_cmd[4] = ' ' + highlight_cmd[5] = attributes else -- The `highlight_group` is uniquely defined. - colorize(highlight_cmd, attributes) + -- Take care of special instructions for certain background colors. + if attributes[vim.o.background] then + attributes = use_background_with(attributes) + end - local style = attributes.style or NONE - if type(style) == 'table' then + colorize(highlight_cmd, attributes) + blend(highlight_cmd, attributes) + + local style = attributes.style or _NONE + + if type(style) == _TYPE_TABLE then -- Concat all of the entries together with a comma between before styling. stylize(highlight_cmd, table.concat(style, ','), style.color) else -- The style is just a single entry. @@ -101,23 +149,56 @@ function yolokai.highlight(highlight_group, attributes) -- {{{ † end end - vim.cmd(table.concat(highlight_cmd)) + exe(table.concat(highlight_cmd)) end --}}} ‡ function yolokai:highlight_terminal(terminal_ansi_colors) - if self.using_hex_or_256 then for index, color in ipairs(terminal_ansi_colors) do - vim.g['terminal_color_'..index] = vim.o.termguicolors and color[PALETTE_HEX] or color[PALETTE_256] - end end + for index, color in ipairs(terminal_ansi_colors) do + vim.g['terminal_color_'..index] = vim.o.termguicolors and color[_PALETTE_HEX] or color[_PALETTE_256] or get(color, _PALETTE_ANSI) + end end return setmetatable(yolokai, { ['__call'] = function(self, normal, highlights, terminal_ansi_colors) + -- function to resolve function highlight groups being defined by function calls. + local function resolve(tbl, key, resolve_links) + local value = tbl[key] + local value_type = type(value) + if value_type == 'function' then + -- lazily cache the result; next time, if it isn't a function this step will be skipped + tbl[key] = value(setmetatable({}, { + ['__index'] = function(_, inner_key) return resolve(tbl, inner_key, true) end + })) + elseif value_type == _TYPE_STRING and not string.find(value, '^#') and resolve_links then + return resolve(tbl, tbl[key], resolve_links) + end + + return tbl[key] + end + + + -- save the colors_name before syntax reset + local color_name = vim.g.colors_name + + -- Clear the highlighting. + exe 'hi clear' + + -- If the syntax has been enabled, reset it. + if fn.exists 'syntax_on' then exe 'syntax reset' end + + -- replace the colors_name + vim.g.colors_name = color_name + color_name = nil + + -- If we aren't using hex nor 256 colorsets. + if not (_USE_HEX or _USE_256) then vim.o.t_Co = '16' end + -- Highlight the baseline. self.highlight('Normal', normal) -- Highlight everything else. - for highlight_group, attributes in pairs(highlights) do - self.highlight(highlight_group, attributes) + for highlight_group, _ in pairs(highlights) do + self.highlight(highlight_group, resolve(highlights, highlight_group, false)) end -- Set the terminal highlight colors.