Skip to content

Commit 6e59aea

Browse files
committed
fix(autocmds): don't clobber winhl nvim option
The user might have their own, custom hlgroup mappings in `winhl` that we shouldn't be clobbering when they don't conflict with ours. Also cleanup `autocmds.lua` and ensure that autocmds ALWAYS get defined/cleared when the colorscheme changes, and make it impossible for the same autocmd to get defined multiple times.
1 parent e5d683f commit 6e59aea

File tree

4 files changed

+73
-32
lines changed

4 files changed

+73
-32
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ The format is based on [Keep a Changelog], and this project adheres to [Semantic
2424

2525
- Made `Color()` constructor idempotent (previously, passing a `Color` inst silently caused a bug)
2626
- Fixed unable to override/customize spec (#359)
27+
- Fixed `winhl` gets clobbered when set
2728

2829
## [v1.1.0] - 23 July 2024
2930

lua/github-theme/autocmds.lua

+17-28
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,43 @@
1-
local config = require('github-theme.config')
2-
3-
local M = {
4-
checked_autocmds = false,
5-
}
1+
local api = vim.api
2+
local M = {}
63

74
M.set_autocmds = function()
8-
if M.checked_deprecation then
9-
return
10-
end
11-
12-
local group = vim.api.nvim_create_augroup(config.theme, { clear = false })
5+
local config = require('github-theme.config')
6+
local util = require('github-theme.util')
7+
local group = api.nvim_create_augroup(config.theme, { clear = true })
8+
local winhl = { Normal = 'NormalSB', SignColumn = 'SignColumnSB' }
139

14-
-- Delete the github-theme autocmds when the theme changes to something else
15-
vim.api.nvim_create_autocmd('ColorScheme', {
10+
api.nvim_create_autocmd('ColorSchemePre', {
11+
desc = 'Cleanup (autocmds, etc.)',
1612
pattern = '*',
1713
group = group,
18-
callback = function()
19-
if vim.g.colors_name ~= config.theme then
20-
pcall(vim.api.nvim_del_augroup_by_id, group)
21-
end
14+
once = true,
15+
callback = function(ev)
16+
pcall(api.nvim_del_augroup_by_id, ev.group)
2217
end,
2318
})
2419

25-
local func_winhightlight = function()
26-
vim.wo.winhighlight = 'Normal:NormalSB,SignColumn:SignColumnSB'
27-
end
28-
2920
for _, sidebar in ipairs(config.options.darken.sidebars.list) do
3021
if sidebar == 'terminal' then
31-
-- Set dark color for terminal background.,
32-
vim.api.nvim_create_autocmd('TermOpen', {
22+
api.nvim_create_autocmd('TermOpen', {
23+
desc = 'Darken terminal bg',
3324
pattern = '*',
3425
group = group,
3526
callback = function()
36-
func_winhightlight()
27+
util.set_winhl(0, winhl)
3728
end,
3829
})
3930
else
40-
-- Set dark color for custom sidebars background.
41-
vim.api.nvim_create_autocmd('FileType', {
31+
api.nvim_create_autocmd('FileType', {
32+
desc = 'Darken sidebar bg',
4233
pattern = sidebar,
4334
group = group,
4435
callback = function()
45-
func_winhightlight()
36+
util.set_winhl(0, winhl)
4637
end,
4738
})
4839
end
4940
end
50-
51-
M.checked_autocmds = true
5241
end
5342

5443
return M

lua/github-theme/util/init.lua

+54-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
1+
local api = vim.api
2+
3+
---@class GhTheme.Util
4+
---@field cache_home string
15
local M = {}
26

3-
---Round float to nearest int
7+
---Rounds a float to the nearest integer.
48
---@param x number Float
59
---@return number
610
function M.round(x)
711
return x >= 0 and math.floor(x + 0.5) or math.ceil(x - 0.5)
812
end
913

10-
---Clamp value between the min and max values.
14+
---Clamps `value` between the min and max values.
1115
---@param value number
1216
---@param min number
1317
---@param max number
@@ -61,6 +65,53 @@ function M.ensure_dir(path)
6165
end
6266
end
6367

64-
M.cache_home = vim.fn.stdpath('cache')
68+
---Sets `winhl` without clobbering any existing mappings (i.e. of highlight groups not
69+
---in `mappings`). Currently only supports setting `winhl` locally (which is likely what
70+
---you want if the mappings are buffer-specific).
71+
---@param win integer window to set the mappings on; use `0` for the current window
72+
---@param mappings table<string, string|false>|false table of mappings to set (or clear if `false`)
73+
function M.set_winhl(win, mappings)
74+
api.nvim_win_call(win == 0 and api.nvim_get_current_win() or win, function()
75+
if not mappings then
76+
-- Clear local mappings and use global values.
77+
vim.opt_local.winhl = nil
78+
return
79+
end
80+
81+
local res = {}
82+
83+
do
84+
-- NOTE: `lower()` is used here because highlight groups are case-insensitive and
85+
-- nvim does not account for this (e.g. when doing `vim.opt_local.winhl:append()`)
86+
local mappings_lower = {}
87+
for from, to in pairs(mappings) do
88+
local from_lower = from:lower()
89+
90+
if mappings_lower[from_lower] then
91+
error('duplicate mapping: ' .. from)
92+
end
93+
94+
-- Coerce false to `nil` (`false` clears a mapping).
95+
res[from], mappings_lower[from_lower] = to or nil, true
96+
end
97+
98+
for old_from, old_to in pairs(vim.opt_local.winhl:get()) do
99+
if mappings_lower[old_from:lower()] == nil then
100+
res[old_from] = old_to
101+
end
102+
end
103+
end
104+
105+
vim.opt_local.winhl = res
106+
end)
107+
end
108+
109+
setmetatable(M, {
110+
__index = function(_, k)
111+
if k == 'cache_home' then
112+
return vim.fn.stdpath('cache')
113+
end
114+
end,
115+
})
65116

66117
return M

test/github-theme/config/overrides_spec.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,6 @@ describe('config > specs', function()
131131
assert.equals('#654321', spec.bg1)
132132

133133
vim.cmd.colorscheme({ args = { 'github_dark_dimmed' } })
134-
assert.same(tonumber('654321', 16), t_util.get_hl('Normal').bg)
134+
assert.equals(tonumber('654321', 16), t_util.get_hl('Normal').bg)
135135
end)
136136
end)

0 commit comments

Comments
 (0)