Skip to content

Commit 52a9d4c

Browse files
authored
fix(compiler): consider entire config when hashing (#350)
- Hash entire config instead of just the table passed to `setup()`. This helps to ensure that a recompilation occurs when overrides are set outside of `setup()`. - Loading/sourcing colorscheme now causes recompilation if config or overrides have changed, even if `setup()` has been called before. - Clear `vim.g.colors_name` before setting `vim.o.background` so that colorscheme is not reloaded recursively when setting `vim.o.background` (as opposed to using a variable to check for nested colorscheme load, which is what we were doing before). - fix(compiler): always write hash to filesystem when a compilation occurs, incl. when `require('github-theme').compile()` is called directly. Related: #262, #340, #341
1 parent 40b5489 commit 52a9d4c

File tree

8 files changed

+104
-71
lines changed

8 files changed

+104
-71
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1313
- Improved highlight-group overrides (#349)
1414
- Assigning `false` or an empty table to a highlight group clears it
1515
- Assigning `false` to groups/specs/palettes clears previous settings from the config store
16+
- Loading/sourcing colorscheme now causes recompilation if config or overrides changed, even if `setup()` has been called before
1617

1718
### Changes
1819

@@ -21,10 +22,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2122

2223
### Issues Fix
2324

24-
- Fixed `punctuation.delimiter` treesitter group nearly invisible (#329 fixed by #331)
25+
- Fixed `punctuation.delimiter` treesitter group nearly invisible (#329 fixed-by #331)
2526
- Closed #305 (no longer valid, fixed)
2627
- Closed #292 (no longer valid, fixed)
2728
- fix(config): `options.darken.floats` is not used (#345)
29+
- fix(compiler): consider entire config when hashing (#350) (related-to #262, #340, #341)
30+
- fix(compiler): always write hash to filesystem when compilation occurs incl. when `require('github-theme').compile()` is called directly (#350)
2831

2932
## [v1.0.2] - 03 May 2023
3033

lua/github-theme/_test/util.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local M = {}
1+
local M = { unique_hlgroup = '____0' }
22
local api = vim.api
33

44
function M.await_VimEnter()

lua/github-theme/init.lua

+56-60
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
local config = require('github-theme.config')
2+
local override = require('github-theme.override')
3+
local keys = { 'palettes', 'specs', 'groups' }
4+
local did_setup = false
5+
local M = {}
26

37
local function read_file(filepath)
48
local file = io.open(filepath, 'r')
@@ -17,99 +21,91 @@ local function write_file(filepath, content)
1721
end
1822
end
1923

20-
local M = {}
21-
2224
function M.reset()
2325
require('github-theme.config').reset()
2426
require('github-theme.override').reset()
2527
end
2628

2729
---Compiles all themes/styles with their current settings.
30+
---@param force boolean true by default
2831
---@return nil
29-
function M.compile()
30-
require('github-theme.lib.log').clear()
31-
local compiler = require('github-theme.lib.compiler')
32-
local themes = require('github-theme.palette').themes
33-
local current_theme = config.theme
34-
for _, theme in ipairs(themes) do
35-
-- Compile current theme last (see discussion in #290)
36-
if theme ~= current_theme then
37-
compiler.compile({ theme = theme })
38-
end
39-
end
40-
compiler.compile({ theme = current_theme })
41-
end
32+
function M.compile(force)
33+
local util = require('github-theme.util')
34+
util.ensure_dir(config.options.compile_path)
4235

43-
-- Avoid g:colors_name reloading
44-
local lock = false
45-
local did_setup = false
36+
local cached_path = util.join_paths(config.options.compile_path, 'cache')
37+
local cached = read_file(cached_path)
38+
local git_path =
39+
vim.fn.fnamemodify(vim.fn.resolve(debug.getinfo(1).source:sub(2)), ':p:h:h:h')
40+
local git = vim.fn.getftime(util.join_paths(git_path, '.git'))
4641

47-
function M.load(opts)
48-
if lock then
49-
return
42+
-- This is needed because neither `opts` nor `config` necessarily contain
43+
-- everything we need to hash. For example, `opts` may not contain all
44+
-- overrides and config currently in use (`setup()` might have been called
45+
-- before, or maybe overrides were set directly and outside of `setup()`), and
46+
-- `config` does not contain any of the overrides in use. Therefore, we need
47+
-- to create a new table which contains everything in-use.
48+
local dummy = { options = config.options }
49+
for _, k in ipairs(keys) do
50+
dummy[k] = override[k]
5051
end
5152

52-
if not did_setup then
53-
M.setup()
53+
local hash = require('github-theme.lib.hash')(dummy) .. (git == -1 and git_path or git)
54+
55+
if force ~= false or cached ~= hash then
56+
require('github-theme.lib.log').clear()
57+
local compiler = require('github-theme.lib.compiler')
58+
local themes = require('github-theme.palette').themes
59+
local current_theme = config.theme
60+
61+
for _, theme in ipairs(themes) do
62+
-- Compile current theme last (see discussion in #290)
63+
if theme ~= current_theme then
64+
compiler.compile({ theme = theme })
65+
end
66+
end
67+
68+
compiler.compile({ theme = current_theme })
69+
write_file(cached_path, hash)
5470
end
5571

56-
opts = opts or {}
72+
getmetatable(override).__index.changed_since_last_compile = false
73+
end
5774

75+
function M.load(opts)
76+
opts = opts or {}
5877
local _, compiled_file = config.get_compiled_info(opts)
59-
lock = true
60-
6178
local f = loadfile(compiled_file)
62-
if not f then
63-
M.compile()
79+
80+
if not did_setup or override.changed_since_last_compile or not f then
81+
M.setup()
6482
f = loadfile(compiled_file)
6583
end
6684

6785
---@diagnostic disable-next-line: need-check-nil
6886
f()
69-
7087
require('github-theme.autocmds').set_autocmds()
71-
lock = false
7288
end
7389

74-
M.setup = function(opts)
75-
did_setup = true
90+
---Applies any new config or overrides then (re)compiles if needed.
91+
---@param opts? table
92+
function M.setup(opts)
7693
opts = opts or {}
77-
78-
local override = require('github-theme.override')
94+
did_setup = true
7995

8096
-- New configs
8197
if opts.options then
8298
config.set_options(opts.options)
8399
end
84100

85-
if opts.palettes ~= nil then
86-
override.palettes = opts.palettes
87-
end
88-
89-
if opts.specs ~= nil then
90-
override.specs = opts.specs
91-
end
92-
93-
if opts.groups ~= nil then
94-
override.groups = opts.groups
95-
end
96-
97-
local util = require('github-theme.util')
98-
util.ensure_dir(config.options.compile_path)
99-
100-
local cached_path = util.join_paths(config.options.compile_path, 'cache')
101-
local cached = read_file(cached_path)
102-
103-
local git_path =
104-
vim.fn.fnamemodify(vim.fn.resolve(debug.getinfo(1).source:sub(2)), ':p:h:h:h')
105-
local git = vim.fn.getftime(util.join_paths(git_path, '.git'))
106-
local hash = require('github-theme.lib.hash')(opts) .. (git == -1 and git_path or git)
107-
108-
if cached ~= hash then
109-
M.compile()
110-
write_file(cached_path, hash)
101+
for _, k in ipairs(keys) do
102+
local v = opts[k]
103+
if v ~= nil then
104+
override[k] = v
105+
end
111106
end
112107

108+
M.compile(false)
113109
require('github-theme.util.deprecation').check_deprecation(opts)
114110
end
115111

lua/github-theme/lib/compiler.lua

+8-5
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ function M.compile(opts)
3838
[[
3939
return string.dump(function()
4040
local h = vim.api.nvim_set_hl
41-
if vim.g.colors_name then vim.cmd("hi clear") end
41+
if vim.g.colors_name then
42+
vim.cmd("hi clear")
43+
vim.g.colors_name = nil
44+
end
4245
vim.o.termguicolors = true
43-
vim.g.colors_name = "%s"
4446
vim.o.background = "%s"
45-
]],
46-
opts.theme,
47-
background
47+
vim.g.colors_name = "%s"
48+
]],
49+
background,
50+
opts.theme
4851
),
4952
}
5053

lua/github-theme/override.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
local collect = require('github-theme.lib.collect')
21
local M = {}
32

43
function M.reset()
54
getmetatable(M).__index =
6-
{ palettes = {}, specs = {}, groups = {}, has_override = false }
5+
{ palettes = {}, specs = {}, groups = {}, changed_since_last_compile = false }
76
return M
87
end
98

@@ -43,6 +42,8 @@ setmetatable(M, {
4342
local store = getmetatable(self).__index
4443

4544
if type(store[k]) == 'table' then
45+
store.changed_since_last_compile = true
46+
4647
if not v then
4748
store[k] = {}
4849
elseif k == 'groups' then
+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
local assert = require('luassert')
2+
local t_util = require('github-theme._test.util')
3+
local uniqgrp = t_util.unique_hlgroup
4+
5+
if vim.fn.has('nvim-0.9.0') == 0 or vim.fn.has('nvim-0.9.0') == false then
6+
return
7+
end
8+
9+
describe('compiler', function()
10+
before_each(function()
11+
require('github-theme.util.reload')(true)
12+
end)
13+
14+
it('should consider previously-set overrides (1)', function()
15+
local same_opts = {}
16+
require('github-theme').setup(same_opts)
17+
require('github-theme.override').groups = { all = { Normal = { link = uniqgrp } } }
18+
require('github-theme').setup(same_opts)
19+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
20+
assert.same({ link = uniqgrp }, t_util.get_hl('Normal', true))
21+
end)
22+
23+
it('should consider previously-set overrides (2)', function()
24+
require('github-theme').setup({})
25+
require('github-theme.override').groups = { all = { Normal = { link = uniqgrp } } }
26+
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
27+
assert.same({ link = uniqgrp }, t_util.get_hl('Normal', true))
28+
end)
29+
end)

test/github-theme/smoketest/startup_spec.lua

+1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ describe('(smoke test)', function()
2727
end)
2828

2929
assert.is.equal('', vim.v.errmsg or '')
30+
assert.is.equal(cs, vim.g.colors_name)
3031
end
3132
end)
3233
end)

test/minimal_init.vim

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@ lua <<
33
vim.loader.disable()
44
end
55
.
6-
set rtp+=.
7-
set rtp+=./test/plenary
6+
set rtp^=.
7+
set rtp^=./test/plenary
88
runtime! plugin/plenary.vim

0 commit comments

Comments
 (0)