Skip to content

Commit 40b5489

Browse files
authored
feat(overrides): improve 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 (like `reset()` but finer-grained) - (internal) Use `false` instead of `link = ''` to mark groups which should be cleared when set - Improve `github-theme.group` - Improve/cleanup code and other minor improvements (code-sharing, simplification, etc.)
1 parent 23484d2 commit 40b5489

File tree

9 files changed

+178
-49
lines changed

9 files changed

+178
-49
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010
### What's New?
1111

1212
- Added new highlight groups for mini.nvim (#333 by @echasnovski)
13+
- Improved highlight-group overrides (#349)
14+
- Assigning `false` or an empty table to a highlight group clears it
15+
- Assigning `false` to groups/specs/palettes clears previous settings from the config store
1316

1417
### Changes
1518

lua/github-theme/_test/util.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ function M.get_hl(group, link)
2929
})
3030
end
3131

32-
if vim.fn.has('nvim-0.10.0') == false or vim.fn.has('nvim-0.10.0') == 0 then
32+
if vim.fn.has('nvim-0.10.0') == 0 or vim.fn.has('nvim-0.10.0') == false then
3333
function M.get_hl(group, link)
3434
return api.nvim_get_hl(0, {
3535
name = group,

lua/github-theme/group.lua

+13-23
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
local collect = require('github-theme.lib.collect')
22
local template = require('github-theme.util.template')
3-
3+
local override = require('github-theme.override')
44
local M = {}
55

6-
local function override(groups, spec, ovr)
7-
ovr = template.parse(ovr, spec)
8-
-- If `set = {}` in override,
9-
-- the corresponding group is deleted.
10-
-- https://github.com/projekt0n/github-nvim-theme/issues/249
11-
for k, v in pairs(ovr) do
12-
if v.link == '' then
13-
groups[k] = nil
14-
end
15-
end
16-
return collect.deep_extend(groups, ovr)
17-
end
18-
196
function M.from(spec)
20-
local ovr = require('github-theme.override').groups
217
local config = require('github-theme.config').options
228

239
if not spec then
@@ -26,7 +12,7 @@ function M.from(spec)
2612
local editor = require('github-theme.group.editor').get(spec, config)
2713
local syntax = require('github-theme.group.syntax').get(spec, config)
2814

29-
local result = collect.deep_extend(editor, syntax)
15+
local res = collect.deep_extend(editor, syntax)
3016

3117
local default_enable_value = config.module_default
3218
local mod_names = require('github-theme.config').module_names
@@ -38,25 +24,29 @@ function M.from(spec)
3824
opts.enable = opts.enable == nil and default_enable_value or opts.enable
3925

4026
if opts.enable then
41-
result = collect.deep_extend(
42-
result,
27+
res = collect.deep_extend(
28+
res,
4329
require('github-theme.group.modules.' .. name).get(spec, config, opts)
4430
)
4531
end
4632
end
4733

48-
local function apply_ovr(key, groups)
49-
return ovr[key] and override(groups, spec, ovr[key]) or groups
34+
local ovr = override.groups
35+
36+
if ovr.all then
37+
override.extend_groups(res, template.parse(ovr.all, spec), {})
5038
end
5139

52-
result = apply_ovr('all', result)
53-
result = apply_ovr(spec.palette.meta.name, result)
40+
if ovr[spec.palette.meta.name] then
41+
override.extend_groups(res, template.parse(ovr[spec.palette.meta.name], spec), {})
42+
end
5443

55-
return result
44+
return res
5645
end
5746

5847
function M.load(name)
5948
name = name or require('github-theme.config').theme
6049
return M.from(require('github-theme.spec').load(name))
6150
end
51+
6252
return M

lua/github-theme/init.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,15 @@ M.setup = function(opts)
8282
config.set_options(opts.options)
8383
end
8484

85-
if opts.palettes then
85+
if opts.palettes ~= nil then
8686
override.palettes = opts.palettes
8787
end
8888

89-
if opts.specs then
89+
if opts.specs ~= nil then
9090
override.specs = opts.specs
9191
end
9292

93-
if opts.groups then
93+
if opts.groups ~= nil then
9494
override.groups = opts.groups
9595
end
9696

lua/github-theme/override.lua

+31-10
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,48 @@ function M.hash()
1111
return require('github-theme.lib.hash')(getmetatable(M).__index) or 0
1212
end
1313

14-
local function check_link(tbl)
15-
for _, theme in pairs(tbl) do
16-
for _, opts in pairs(theme) do
17-
opts.link = opts.link or ''
14+
---Extends `groups` with `overrides`. `groups` is modified in-place.
15+
---@generic T: table<string, table|false>
16+
---@param groups T a table of highlight groups
17+
---@param overrides T | nil
18+
---@param nullval any the marker to use for cleared groups
19+
---@return T groups
20+
function M.extend_groups(groups, overrides, nullval)
21+
for grp_name, grp in pairs(overrides or {}) do
22+
if grp == false or next(grp) == nil then
23+
-- clear the group
24+
groups[grp_name] = nullval
25+
else
26+
-- `link` is not compatible with other settings
27+
if grp.link then
28+
groups[grp_name] = { link = grp.link }
29+
else
30+
groups[grp_name] = vim.tbl_deep_extend('force', groups[grp_name] or {}, grp)
31+
32+
-- Clear previous `link`, or `grp.link = false`
33+
groups[grp_name].link = nil
34+
end
1835
end
1936
end
37+
38+
return groups
2039
end
2140

2241
setmetatable(M, {
2342
__newindex = function(self, k, v)
2443
local store = getmetatable(self).__index
44+
2545
if type(store[k]) == 'table' then
2646
if not v then
2747
store[k] = {}
28-
return
29-
end
30-
if k == 'groups' then
31-
check_link(v)
48+
elseif k == 'groups' then
49+
for theme, grps in pairs(v) do
50+
store.groups[theme] = store.groups[theme] or {}
51+
M.extend_groups(store.groups[theme], grps, false)
52+
end
53+
else
54+
store[k] = vim.tbl_deep_extend('force', store[k], v)
3255
end
33-
store[k] = collect.deep_extend(store[k], v)
34-
store.has_override = true
3556
end
3657
end,
3758
})

lua/github-theme/util/reload.lua

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
1-
local function reload()
2-
for name, _ in pairs(package.loaded) do
3-
if name:match('^github-theme') then
1+
---@param force? boolean
2+
local function reload(force)
3+
for name, _ in pairs(_G.package.loaded) do
4+
if name:find('^github%-theme') then
45
if
5-
not name:match('config')
6-
and not name:match('deprecation')
7-
and not name:match('override')
6+
force
7+
or (
8+
not name:find('config')
9+
and not name:find('deprecation')
10+
and not name:find('override')
11+
)
812
then
9-
package.loaded[name] = nil
13+
_G.package.loaded[name] = nil
1014
end
1115
end
1216
end
1317
end
1418

1519
return setmetatable({}, {
16-
__call = function(_)
17-
reload()
20+
__call = function(_, ...)
21+
reload(...)
1822
end,
1923
})

test/github-theme/config/darken_spec.lua

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
local assert = require('luassert')
22
local t_util = require('github-theme._test.util')
33
local C = require('github-theme.lib.color')
4-
local api = vim.api
54

6-
if not api.nvim_get_hl then
5+
if vim.fn.has('nvim-0.9.0') == 0 or vim.fn.has('nvim-0.9.0') == false then
76
return
87
end
98

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
local assert = require('luassert')
2+
local t_util = require('github-theme._test.util')
3+
4+
if vim.fn.has('nvim-0.9.0') == 0 or vim.fn.has('nvim-0.9.0') == false then
5+
return
6+
end
7+
8+
describe('config > groups', function()
9+
before_each(function()
10+
require('github-theme.util.reload')(true)
11+
end)
12+
13+
it('should allow clearing a group via empty table (1)', function()
14+
require('github-theme').setup({ groups = { all = { Normal = {} } } })
15+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
16+
assert.same({}, t_util.get_hl('Normal'))
17+
end)
18+
19+
it('should allow clearing a group via empty table (2)', function()
20+
require('github-theme').setup({
21+
groups = {
22+
github_dark_dimmed = { Normal = {} },
23+
all = { Normal = { fg = '#123456', bg = '#654321' } },
24+
},
25+
})
26+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
27+
assert.same({}, t_util.get_hl('Normal'))
28+
end)
29+
30+
it('clearing group combines properly with more-specific overrides', function()
31+
require('github-theme').setup({
32+
groups = {
33+
all = { Normal = {} },
34+
github_dark_dimmed = { Normal = { fg = '#123456', bg = '#654321' } },
35+
},
36+
})
37+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
38+
assert.same(
39+
{ fg = tonumber('123456', 16), bg = tonumber('654321', 16) },
40+
t_util.get_hl('Normal')
41+
)
42+
end)
43+
44+
it('should allow overriding a group', function()
45+
require('github-theme').setup({
46+
groups = { all = { Normal = { fg = '#123456', bg = '#654321' } } },
47+
})
48+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
49+
assert.same(
50+
{ fg = tonumber('123456', 16), bg = tonumber('654321', 16) },
51+
t_util.get_hl('Normal')
52+
)
53+
end)
54+
55+
it('overriding group combines properly with more-specific overrides (1)', function()
56+
require('github-theme').setup({
57+
groups = {
58+
all = { Normal = { link = 'NormalNC' } },
59+
github_dark_dimmed = { Normal = { fg = '#123456', bg = '#654321' } },
60+
},
61+
})
62+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
63+
assert.is_nil(t_util.get_hl('Normal', true).link)
64+
end)
65+
66+
it('overriding group combines properly with more-specific overrides (2)', function()
67+
require('github-theme').setup({
68+
groups = {
69+
all = { Normal = { fg = '#123456', bg = '#654321' } },
70+
github_dark_dimmed = { Normal = { link = 'NormalNC' } },
71+
},
72+
})
73+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
74+
assert.same({ link = 'NormalNC' }, t_util.get_hl('Normal', true))
75+
end)
76+
77+
it('should allow linking a group', function()
78+
require('github-theme').setup({
79+
groups = { all = { Normal = { link = 'NormalNC' } } },
80+
})
81+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
82+
assert.same({ link = 'NormalNC' }, t_util.get_hl('Normal', true))
83+
end)
84+
85+
it('should not be affected by a previous override using `link`', function()
86+
require('github-theme').setup({
87+
groups = {
88+
all = { Normal = { link = 'NormalNC' } },
89+
},
90+
})
91+
require('github-theme').setup({
92+
groups = {
93+
all = { Normal = { fg = '#123456', bg = '#654321' } },
94+
},
95+
})
96+
97+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
98+
assert.same(
99+
{ fg = '#123456', bg = '#654321' },
100+
require('github-theme.override').groups.all.Normal
101+
)
102+
assert.is_nil(t_util.get_hl('Normal', true).link)
103+
assert.same(
104+
{ fg = tonumber('123456', 16), bg = tonumber('654321', 16) },
105+
t_util.get_hl('Normal')
106+
)
107+
end)
108+
end)

test/minimal_init.vim

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
lua vim.loader.disable()
1+
lua <<
2+
if vim.fn.has('nvim-0.9.0') == 1 or vim.fn.has('nvim-0.9.0') == true then
3+
vim.loader.disable()
4+
end
5+
.
26
set rtp+=.
37
set rtp+=./test/plenary
48
runtime! plugin/plenary.vim

0 commit comments

Comments
 (0)