Skip to content

Commit 742c701

Browse files
authored
fix(Color): don't use shared global state (Color.BG etc.) (#363)
Fix bug where the colorscheme colors are off/incorrect when a palette is require()'d, whether directly or indirectly, anytime before compilation occurs (e.g. compilation that occurs during colorscheme load). For details, see issue #362. Also, add a test (in `test/`) which disallows the direct or indirect use of the global static/class fields of the `Color` class (e.g. `Color.BG`). Fixes: #362
1 parent 770d1b5 commit 742c701

17 files changed

+405
-379
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
1414
### Issues Fix
1515

1616
- Fixed JSX/TSX tags are missing highlights with nvim 0.10 (#360)
17+
- Fixed loading palette or spec before colorscheme disrupts colors (#362 fixed-by #363)
1718

1819
## [v1.1.2] - 05 August 2024
1920

lua/github-theme/group/modules/treesitter.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ function M.get(spec, config, _opts)
88
-- being integrated.
99
local primitives = require(
1010
'github-theme.palette.primitives.'
11-
.. require('github-theme.config').theme
11+
.. spec.palette.meta.name
1212
:gsub('^github_(.-)_default$', '%1')
1313
:gsub('^github_(.-)$', '%1')
1414
)

lua/github-theme/init.lua

+22-6
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ function M.compile(force)
5252

5353
local hash = require('github-theme.lib.hash')(dummy) .. (git == -1 and git_path or git)
5454

55+
-- Compile
5556
if force ~= false or cached ~= hash then
5657
require('github-theme.lib.log').clear()
5758
local compiler = require('github-theme.lib.compiler')
@@ -84,15 +85,15 @@ function M.load(opts)
8485
end
8586

8687
local _, compiled_file = config.get_compiled_info(opts)
87-
local f = loadfile(compiled_file)
88+
local compiled_theme = loadfile(compiled_file)
8889

89-
if not did_setup or override.changed_since_last_compile or not f then
90+
if not did_setup or override.changed_since_last_compile or not compiled_theme then
9091
M.setup()
91-
f = loadfile(compiled_file)
92+
compiled_theme = loadfile(compiled_file)
9293
end
9394

9495
---@diagnostic disable-next-line: need-check-nil
95-
f()
96+
compiled_theme()
9697
require('github-theme.autocmds').set_autocmds()
9798
end
9899

@@ -115,8 +116,23 @@ function M.setup(opts)
115116
end
116117
end
117118

118-
M.compile(false)
119-
require('github-theme.util.deprecation').check_deprecation(opts)
119+
M.compile(not not vim.g.github_theme_force_compile)
120+
121+
-- Use our 1 time to check for deprecations the first time `setup()` is called with
122+
-- opts, instead of the first time `setup()` is called at all.
123+
if next(opts) ~= nil then
124+
-- TODO: might be better to call this and emit notices whenever config changes and on
125+
-- 1st load/setup(), while filtering deprecation messages at the msg level instead of
126+
-- globally.
127+
require('github-theme.util.deprecation').check_deprecation(opts)
128+
end
129+
end
130+
131+
-- Mainly for debugging, testing, development, etc.
132+
for _, env in ipairs({ 'GITHUB_THEME_DEBUG', 'GITHUB_THEME_FORCE_COMPILE' }) do
133+
if vim.env[env] then
134+
vim.g[env:lower()] = true
135+
end
120136
end
121137

122138
return M

lua/github-theme/lib/color.lua

+13-15
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ end
336336

337337
---Returns a new Color that is a linear blend between `self` and `other`.
338338
---@param other GhTheme.Color
339-
---@param f number Float [0,1] where 0 is `self` and 1 is `other`
339+
---@param f number float `[0,1]` where `0` is `self` and `1` is `other`
340340
---@return GhTheme.Color
341341
---@nodiscard
342342
function Color:blend(other, f)
@@ -349,20 +349,18 @@ function Color:blend(other, f)
349349
end
350350

351351
---Returns a new Color that is a linear blend between `Color.BG` and `self`.
352-
---@param f number Float [0,1] where 0 is `Color.BG` and 1 is `self`
352+
---
353+
---> WARNING: This method might not work correctly until ***after*** the colorscheme has
354+
---> loaded, or `Color.BG` has been set! DO NOT USE INTERNALLY!
355+
---@param alpha number float (`[0,1]`) where `0` is `Color.BG` and `1` is `self`
353356
---@return GhTheme.Color
354357
---@nodiscard
355-
function Color:alpha_blend(f)
356-
return M.init(
357-
(self.red - self.BG.red) * f + self.BG.red,
358-
(self.green - self.BG.green) * f + self.BG.green,
359-
(self.blue - self.BG.blue) * f + self.BG.blue,
360-
self.alpha
361-
)
358+
function Color:alpha_blend(alpha)
359+
return self.BG:blend(self, alpha)
362360
end
363361

364362
---Returns a new Color which is `self` shaded according to `f`.
365-
---@param f number Amount. Float [-1,1]. -1 is black and 1 is white
363+
---@param f number float (`[-1,1]`) where `-1` is black and `1` is white
366364
---@return GhTheme.Color
367365
---@nodiscard
368366
function Color:shade(f)
@@ -377,9 +375,9 @@ function Color:shade(f)
377375
)
378376
end
379377

380-
---Adds value of `v` to the `value` of the current color. Returns a new Color
381-
---that is either a brighter version (v >= 0), or darker (v < 0).
382-
---@param v number Value. Float [-100,100].
378+
---Adds value of `v` to the `value` of the current color. Returns a new Color that is
379+
---either a brighter version (`v >= 0`), or darker (`v < 0`).
380+
---@param v number Value. Float `[-100,100]`.
383381
---@return GhTheme.Color
384382
---@nodiscard
385383
function Color:brighten(v)
@@ -390,7 +388,7 @@ end
390388

391389
---Adds value of `v` to the `lightness` of the current color. Returns a new Color
392390
---that is either a lighter version if +v and darker if -v.
393-
---@param v number Lightness. Float [-100,100].
391+
---@param v number Lightness. Float `[-100,100]`.
394392
---@return GhTheme.Color
395393
---@nodiscard
396394
function Color:lighten(v)
@@ -411,7 +409,7 @@ function Color:saturate(v)
411409
end
412410

413411
---Adds value of `v` to the `hue` of the current color. Returns a new Color where
414-
---the hue is rotated based on +/- of `v`. Resulting `hue` is wrapped [0,360].
412+
---the hue is rotated based on +/- of `v`. Resulting `hue` is wrapped `[0,360]`.
415413
---@param v number amount
416414
---@return GhTheme.Color
417415
---@nodiscard

lua/github-theme/lib/compiler.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ vim.g.colors_name = "%s"
8787

8888
file = io.open(output_file, 'wb')
8989

90-
local f = loadstring(table.concat(lines, '\n'), '=')
91-
if not f then
90+
local dump_theme = loadstring(table.concat(lines, '\n'), 'dump_theme')
91+
if not dump_theme then
9292
local tmpfile = util.join_paths(util.get_tmp_dir(), 'github_theme_error.lua')
9393
require('github-theme.lib.log').error(
9494
fmt(
@@ -109,7 +109,7 @@ Bellow is the error message:
109109
dofile(tmpfile)
110110
end
111111

112-
file:write(f())
112+
file:write(dump_theme())
113113
file:close()
114114
end
115115

lua/github-theme/palette/github_dark.lua

+34-37
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ local scale = primitives.scale
1414
C.WHITE = C(scale.white)
1515
C.BLACK = C(scale.black)
1616
C.BG = C(scale.gray[7])
17-
18-
local function alpha(color, a)
19-
return color:alpha_blend(a):to_css()
20-
end
17+
local BG = C(scale.gray[7])
2118

2219
local palette = {
2320
scale = scale,
@@ -52,86 +49,86 @@ local palette = {
5249
border = {
5350
default = scale.gray[9],
5451
muted = scale.gray[8],
55-
subtle = alpha(C.from_rgba(240, 246, 252, 1), 0.1),
52+
subtle = BG:blend(C.from_rgba(240, 246, 252, 1), 0.1):to_css(),
5653
},
5754

5855
neutral = {
5956
emphasis_plus = scale.gray[5],
6057
emphasis = scale.gray[5],
61-
muted = alpha(C.from_rgba(110, 118, 129, 1), 0.4),
62-
subtle = alpha(C.from_rgba(110, 118, 129, 1), 0.1),
58+
muted = BG:blend(C.from_rgba(110, 118, 129, 1), 0.4):to_css(),
59+
subtle = BG:blend(C.from_rgba(110, 118, 129, 1), 0.1):to_css(),
6360
},
6461

6562
accent = {
6663
fg = '#2f81f7',
6764
emphasis = scale.blue[6],
68-
muted = alpha(C.from_rgba(56, 139, 253, 1), 0.4),
69-
subtle = alpha(C.from_rgba(56, 139, 253, 1), 0.15),
65+
muted = BG:blend(C.from_rgba(56, 139, 253, 1), 0.4):to_css(),
66+
subtle = BG:blend(C.from_rgba(56, 139, 253, 1), 0.15):to_css(),
7067
},
7168

7269
success = {
7370
fg = scale.green[4],
7471
emphasis = scale.green[6],
75-
muted = alpha(C.from_rgba(46, 160, 67, 1), 0.4),
76-
subtle = alpha(C.from_rgba(46, 160, 67, 1), 0.15),
72+
muted = BG:blend(C.from_rgba(46, 160, 67, 1), 0.4):to_css(),
73+
subtle = BG:blend(C.from_rgba(46, 160, 67, 1), 0.15):to_css(),
7774
},
7875

7976
attention = {
8077
fg = scale.yellow[4],
8178
emphasis = scale.yellow[6],
82-
muted = alpha(C.from_rgba(187, 128, 9, 1), 0.4),
83-
subtle = alpha(C.from_rgba(187, 128, 9, 1), 0.15),
79+
muted = BG:blend(C.from_rgba(187, 128, 9, 1), 0.4):to_css(),
80+
subtle = BG:blend(C.from_rgba(187, 128, 9, 1), 0.15):to_css(),
8481
},
8582

8683
severe = {
8784
fg = scale.orange[5],
8885
emphasis = scale.orange[6],
89-
muted = alpha(C.from_rgba(219, 109, 40, 1), 0.4),
90-
subtle = alpha(C.from_rgba(219, 109, 40, 1), 0.1),
86+
muted = BG:blend(C.from_rgba(219, 109, 40, 1), 0.4):to_css(),
87+
subtle = BG:blend(C.from_rgba(219, 109, 40, 1), 0.1):to_css(),
9188
},
9289

9390
danger = {
9491
fg = scale.red[5],
9592
emphasis = scale.red[6],
96-
muted = alpha(C.from_rgba(248, 81, 73, 1), 0.4),
97-
subtle = alpha(C.from_rgba(248, 81, 73, 1), 0.1),
93+
muted = BG:blend(C.from_rgba(248, 81, 73, 1), 0.4):to_css(),
94+
subtle = BG:blend(C.from_rgba(248, 81, 73, 1), 0.1):to_css(),
9895
},
9996

10097
open = {
10198
fg = scale.green[4],
10299
emphasis = scale.green[6],
103-
muted = alpha(C.from_rgba(46, 160, 67, 1), 0.4),
104-
subtle = alpha(C.from_rgba(46, 160, 67, 1), 0.15),
100+
muted = BG:blend(C.from_rgba(46, 160, 67, 1), 0.4):to_css(),
101+
subtle = BG:blend(C.from_rgba(46, 160, 67, 1), 0.15):to_css(),
105102
},
106103

107104
done = {
108105
fg = scale.purple[5],
109106
emphasis = scale.purple[6],
110-
muted = alpha(C.from_rgba(163, 113, 247, 1), 0.4),
111-
subtle = alpha(C.from_rgba(163, 113, 247, 1), 0.1),
107+
muted = BG:blend(C.from_rgba(163, 113, 247, 1), 0.4):to_css(),
108+
subtle = BG:blend(C.from_rgba(163, 113, 247, 1), 0.1):to_css(),
112109
},
113110

114111
closed = {
115112
fg = scale.red[5],
116113
emphasis = scale.red[6],
117-
muted = alpha(C.from_rgba(248, 81, 73, 1), 0.4),
118-
subtle = alpha(C.from_rgba(248, 81, 73, 1), 0.15),
114+
muted = BG:blend(C.from_rgba(248, 81, 73, 1), 0.4):to_css(),
115+
subtle = BG:blend(C.from_rgba(248, 81, 73, 1), 0.15):to_css(),
119116
},
120117

121118
sponsors = {
122119
fg = scale.pink[5],
123120
emphasis = scale.pink[6],
124-
muted = alpha(C.from_rgba(219, 97, 162, 1), 0.4),
125-
subtle = alpha(C.from_rgba(219, 97, 162, 1), 0.1),
121+
muted = BG:blend(C.from_rgba(219, 97, 162, 1), 0.4):to_css(),
122+
subtle = BG:blend(C.from_rgba(219, 97, 162, 1), 0.1):to_css(),
126123
},
127124
}
128125

129126
local function generate_spec(pal)
130127
-- stylua: ignore start
131128
local spec = {
132-
bg0 = alpha(C(pal.canvas.inset), 0.75), -- Dark bg (popup and float)
129+
bg0 = BG:blend(C(pal.canvas.inset), 0.75):to_css(), -- Dark bg (popup and float)
133130
bg1 = pal.canvas.default, -- Default bg
134-
bg2 = alpha(C(pal.neutral.emphasis), 0.1), -- Lighter bg (colorcolumn Folds)
131+
bg2 = BG:blend(C(pal.neutral.emphasis), 0.1):to_css(), -- Lighter bg (colorcolumn Folds)
135132
bg3 = pal.scale.gray[6], -- Lighter bg (cursor line)
136133
bg4 = pal.scale.gray[4], -- Conceal
137134

@@ -140,9 +137,9 @@ local function generate_spec(pal)
140137
fg2 = pal.fg.muted, -- Darker fg (status line)
141138
fg3 = pal.scale.gray[5], -- Darker fg (line numbers, fold columns)
142139

143-
sel0 = alpha(C(pal.accent.fg), 0.30), -- Visual selection bg
144-
sel1 = alpha(C(pal.accent.muted), 0.90), -- Popup sel bg
145-
sel2 = alpha(C(pal.scale.yellow[1]), 0.20), -- Search bg
140+
sel0 = BG:blend(C(pal.accent.fg), 0.30):to_css(), -- Visual selection bg
141+
sel1 = BG:blend(C(pal.accent.muted), 0.90):to_css(), -- Popup sel bg
142+
sel2 = BG:blend(C(pal.scale.yellow[1]), 0.20):to_css(), -- Search bg
146143
}
147144

148145
spec.syntax = {
@@ -178,16 +175,16 @@ local function generate_spec(pal)
178175
}
179176

180177
spec.diag_bg = {
181-
error = C(spec.bg1):blend(C(spec.diag.error), 0.15):to_css(),
182-
warn = C(spec.bg1):blend(C(spec.diag.warn), 0.15):to_css(),
183-
info = C(spec.bg1):blend(C(spec.diag.info), 0.15):to_css(),
184-
hint = C(spec.bg1):blend(C(spec.diag.hint), 0.15):to_css(),
178+
error = BG:blend(C(spec.diag.error), 0.15):to_css(),
179+
warn = BG:blend(C(spec.diag.warn), 0.15):to_css(),
180+
info = BG:blend(C(spec.diag.info), 0.15):to_css(),
181+
hint = BG:blend(C(spec.diag.hint), 0.15):to_css(),
185182
}
186183

187184
spec.diff = {
188-
add = alpha(C(pal.scale.green[6]), 0.15),
189-
delete = alpha(C(pal.scale.red[6]), 0.15),
190-
change = alpha(C(pal.scale.yellow[6]), 0.15),
185+
add = BG:blend(C(pal.scale.green[6]), 0.15):to_css(),
186+
delete = BG:blend(C(pal.scale.red[6]), 0.15):to_css(),
187+
change = BG:blend(C(pal.scale.yellow[6]), 0.15):to_css(),
191188
text = spec.fg0
192189
}
193190

0 commit comments

Comments
 (0)