diff --git a/CHANGELOG.md b/CHANGELOG.md index 0536925..a778c68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### What's New? - Added new highlight groups for mini.nvim (#333 by @echasnovski) +- Improved highlight-group overrides (#349) +- Assigning `false` or an empty table to a highlight group clears it +- Assigning `false` to groups/specs/palettes clears previous settings from the config store ### Changes diff --git a/lua/github-theme/_test/util.lua b/lua/github-theme/_test/util.lua index 24a92fb..7bf1181 100644 --- a/lua/github-theme/_test/util.lua +++ b/lua/github-theme/_test/util.lua @@ -29,7 +29,7 @@ function M.get_hl(group, link) }) end -if vim.fn.has('nvim-0.10.0') == false or vim.fn.has('nvim-0.10.0') == 0 then +if vim.fn.has('nvim-0.10.0') == 0 or vim.fn.has('nvim-0.10.0') == false then function M.get_hl(group, link) return api.nvim_get_hl(0, { name = group, diff --git a/lua/github-theme/group.lua b/lua/github-theme/group.lua index aed77aa..529501d 100644 --- a/lua/github-theme/group.lua +++ b/lua/github-theme/group.lua @@ -1,23 +1,9 @@ local collect = require('github-theme.lib.collect') local template = require('github-theme.util.template') - +local override = require('github-theme.override') local M = {} -local function override(groups, spec, ovr) - ovr = template.parse(ovr, spec) - -- If `set = {}` in override, - -- the corresponding group is deleted. - -- https://github.com/projekt0n/github-nvim-theme/issues/249 - for k, v in pairs(ovr) do - if v.link == '' then - groups[k] = nil - end - end - return collect.deep_extend(groups, ovr) -end - function M.from(spec) - local ovr = require('github-theme.override').groups local config = require('github-theme.config').options if not spec then @@ -26,7 +12,7 @@ function M.from(spec) local editor = require('github-theme.group.editor').get(spec, config) local syntax = require('github-theme.group.syntax').get(spec, config) - local result = collect.deep_extend(editor, syntax) + local res = collect.deep_extend(editor, syntax) local default_enable_value = config.module_default local mod_names = require('github-theme.config').module_names @@ -38,25 +24,29 @@ function M.from(spec) opts.enable = opts.enable == nil and default_enable_value or opts.enable if opts.enable then - result = collect.deep_extend( - result, + res = collect.deep_extend( + res, require('github-theme.group.modules.' .. name).get(spec, config, opts) ) end end - local function apply_ovr(key, groups) - return ovr[key] and override(groups, spec, ovr[key]) or groups + local ovr = override.groups + + if ovr.all then + override.extend_groups(res, template.parse(ovr.all, spec), {}) end - result = apply_ovr('all', result) - result = apply_ovr(spec.palette.meta.name, result) + if ovr[spec.palette.meta.name] then + override.extend_groups(res, template.parse(ovr[spec.palette.meta.name], spec), {}) + end - return result + return res end function M.load(name) name = name or require('github-theme.config').theme return M.from(require('github-theme.spec').load(name)) end + return M diff --git a/lua/github-theme/init.lua b/lua/github-theme/init.lua index dc769bd..37e4208 100644 --- a/lua/github-theme/init.lua +++ b/lua/github-theme/init.lua @@ -82,15 +82,15 @@ M.setup = function(opts) config.set_options(opts.options) end - if opts.palettes then + if opts.palettes ~= nil then override.palettes = opts.palettes end - if opts.specs then + if opts.specs ~= nil then override.specs = opts.specs end - if opts.groups then + if opts.groups ~= nil then override.groups = opts.groups end diff --git a/lua/github-theme/override.lua b/lua/github-theme/override.lua index a47d678..98cf901 100644 --- a/lua/github-theme/override.lua +++ b/lua/github-theme/override.lua @@ -11,27 +11,48 @@ function M.hash() return require('github-theme.lib.hash')(getmetatable(M).__index) or 0 end -local function check_link(tbl) - for _, theme in pairs(tbl) do - for _, opts in pairs(theme) do - opts.link = opts.link or '' +---Extends `groups` with `overrides`. `groups` is modified in-pace. +---@generic T: table +---@param groups T a table of highlight groups +---@param overrides T | nil +---@param nullval any the marker to use for cleared groups +---@return T groups +function M.extend_groups(groups, overrides, nullval) + for grp_name, grp in pairs(overrides or {}) do + if grp == false or next(grp) == nil then + -- clear the group + groups[grp_name] = nullval + else + -- `link` is not compatible with other settings + if grp.link then + groups[grp_name] = { link = grp.link } + else + groups[grp_name] = vim.tbl_deep_extend('force', groups[grp_name] or {}, grp) + + -- Clear previous `link`, or `grp.link = false` + groups[grp_name].link = nil + end end end + + return groups end setmetatable(M, { __newindex = function(self, k, v) local store = getmetatable(self).__index + if type(store[k]) == 'table' then if not v then store[k] = {} - return - end - if k == 'groups' then - check_link(v) + elseif k == 'groups' then + for theme, grps in pairs(v) do + store.groups[theme] = store.groups[theme] or {} + M.extend_groups(store.groups[theme], grps, false) + end + else + store[k] = vim.tbl_deep_extend('force', store[k], v) end - store[k] = collect.deep_extend(store[k], v) - store.has_override = true end end, })