repositories / dotfiles
dotfiles
bugabingas dorkfiles
owned by admin
neovim/tests/manual/compare_highlights.lua
Raw--- Compare cterm highlight snapshot against the original hex baseline.
--- Verifies that every ctermfg/ctermbg index matches the expected nugu color.
--- Usage: nvim --headless /tmp/nugu_compare.txt -c "luafile tests/manual/compare_highlights.lua" -c "qa!"
-- The original hex baseline (captured before the cterm change)
local baseline_path = '/tmp/nugu_highlights_baseline.txt'
-- nugu color mapping: cterm index -> { dark_hex, semantic_name }
local slot_info = {
[0] = { '#121212', 'content_backdrop' },
[1] = { '#e46479', 'error' },
[2] = { '#7ba1aa', 'content_focus' },
[3] = { '#9e9a69', 'warning' },
[4] = { '#b59ae4', 'content_important_local' },
[5] = { '#d151d1', 'content_accent' },
[6] = { '#5d5d5d', 'content_unfocus' },
[7] = { '#ededed', 'content_normal' },
[8] = { '#8b8b8b', 'content_minor' },
[9] = { '#3ec5dd', 'info' },
[10] = { '#6f6f6f', 'ui_unfocus' },
[11] = { '#242424', 'ui_backdrop' },
[12] = { '#dfd3f3', 'content_important_global' },
[13] = { '#d86dd8', 'ui_accent' },
[14] = { '#c9b6eb', 'ui_important_local' },
[15] = { '#f3effb', 'ui_important_global' },
[16] = { '#ed5eed', 'debug' },
[17] = { '#dbdbdb', 'ui_normal' },
[18] = { '#9d9d9d', 'ui_minor' },
[19] = { '#9aabae', 'ui_focus' },
}
-- Build hex -> slot reverse map (lowercase for comparison)
local hex_to_slot = {}
for idx, info in pairs(slot_info) do
hex_to_slot[info[1]:lower()] = idx
end
-- Parse baseline file: group_name -> { fg=hex, bg=hex, sp=hex, bold=bool, ... }
local function parse_file(path)
local f = io.open(path, 'r')
if not f then return {} end
local groups = {}
for line in f:lines() do
if not line:match '^%-%-' and line ~= '' then
local name, rest = line:match '^(%S+) (.+)$'
if name then
local props = {}
for token in rest:gmatch '%S+' do
local k, v = token:match '^(%a+)=(.+)$'
if k then
props[k] = v
else
props[token] = true
end
end
groups[name] = props
end
end
end
f:close()
return groups
end
local baseline = parse_file(baseline_path)
local cterm = parse_file('/tmp/nugu_highlights_cterm.txt')
local outpath = vim.fn.argv()[1] or '/tmp/nugu_compare.txt'
local lines = {
'-- Highlight comparison: hex baseline vs cterm',
'-- ' .. os.date '!%Y-%m-%dT%H:%M:%SZ',
'',
}
local match_count = 0
local mismatch_count = 0
local missing_count = 0
local skipped_count = 0
-- Check all groups that exist in the baseline (nugu-defined groups)
for name, base_props in pairs(baseline) do
local ct = cterm[name]
if not ct then
missing_count = missing_count + 1
lines[#lines + 1] = 'MISSING: ' .. name
else
-- Compare fg
if base_props.fg and ct.ctermfg then
local base_hex = base_props.fg:lower()
local slot = tonumber(ct.ctermfg)
local expected_hex = slot_info[slot] and slot_info[slot][1]:lower()
if base_hex == expected_hex then
match_count = match_count + 1
elseif hex_to_slot[base_hex] then
mismatch_count = mismatch_count + 1
lines[#lines + 1] = string.format(
'MISMATCH FG: %s baseline=%s (slot %d) cterm=%s (slot %d, %s)',
name, base_hex, hex_to_slot[base_hex],
ct.ctermfg, slot, expected_hex or '?'
)
else
-- baseline has a hex that isn't in our palette (built-in default)
skipped_count = skipped_count + 1
end
end
-- Compare bg
if base_props.bg and ct.ctermbg then
local base_hex = base_props.bg:lower()
local slot = tonumber(ct.ctermbg)
local expected_hex = slot_info[slot] and slot_info[slot][1]:lower()
if base_hex == expected_hex then
match_count = match_count + 1
elseif hex_to_slot[base_hex] then
mismatch_count = mismatch_count + 1
lines[#lines + 1] = string.format(
'MISMATCH BG: %s baseline=%s (slot %d) cterm=%s (slot %d, %s)',
name, base_hex, hex_to_slot[base_hex],
ct.ctermbg, slot, expected_hex or '?'
)
else
skipped_count = skipped_count + 1
end
end
-- Check for missing ctermfg when baseline has fg
if base_props.fg and not ct.ctermfg and not ct.link then
local base_hex = base_props.fg:lower()
if hex_to_slot[base_hex] then
missing_count = missing_count + 1
lines[#lines + 1] = 'NO CTERMFG: ' .. name .. ' (baseline fg=' .. base_props.fg .. ')'
end
end
if base_props.bg and not ct.ctermbg and not ct.link then
local base_hex = base_props.bg:lower()
if hex_to_slot[base_hex] then
missing_count = missing_count + 1
lines[#lines + 1] = 'NO CTERMBG: ' .. name .. ' (baseline bg=' .. base_props.bg .. ')'
end
end
-- Compare boolean attributes
for _, attr in ipairs({ 'bold', 'italic', 'underline', 'undercurl', 'underdouble',
'underdotted', 'underdashed', 'strikethrough', 'reverse' }) do
local base_has = base_props[attr] and true or false
local ct_has = ct[attr] and true or false
if base_has ~= ct_has then
lines[#lines + 1] = string.format('ATTR DIFF: %s %s baseline=%s cterm=%s',
name, attr, tostring(base_has), tostring(ct_has))
end
end
end
end
-- Summary
lines[#lines + 1] = ''
lines[#lines + 1] = string.format('Matches: %d', match_count)
lines[#lines + 1] = string.format('Mismatches: %d', mismatch_count)
lines[#lines + 1] = string.format('Missing: %d', missing_count)
lines[#lines + 1] = string.format('Skipped: %d (non-nugu colors)', skipped_count)
local f = assert(io.open(outpath, 'w'))
f:write(table.concat(lines, '\n') .. '\n')
f:close()
print(table.concat(lines, '\n'))