-- Analyze which nugu palette colors are used in highlight groups -- and map them to wezterm ANSI/indexed slots. -- Usage: :luafile tests/manual/analyze_color_usage.lua local palette = require 'bugabinga.nugu.palette' -- Build reverse map: hex -> semantic name local hex_to_name = {} for k, v in pairs(palette) do hex_to_name[v] = k end -- Current wezterm mapping (from wezterm/nugu/init.lua) local ansi_map = { [0] = 'content_backdrop', [1] = 'error', [2] = 'content_focus', [3] = 'warning', [4] = 'content_important_local', [5] = 'content_accent', [6] = 'content_unfocus', [7] = 'content_normal', [8] = 'content_minor', [9] = 'error', -- duplicate [10] = 'ui_unfocus', [11] = 'ui_backdrop', [12] = 'content_important_global', [13] = 'ui_accent', [14] = 'ui_important_local', [15] = 'ui_important_global', } -- Build name -> slot local name_to_slot = {} for slot, name in pairs(ansi_map) do name_to_slot[name] = slot end -- Collect all unique fg/bg/sp colors used local all_hl = vim.api.nvim_get_hl(0, {}) local color_usage = {} -- hex -> { groups={}, as={fg=0, bg=0, sp=0} } for name, hl in pairs(all_hl) do for _, prop in ipairs { 'fg', 'bg', 'sp' } do if hl[prop] then local hex = string.format('#%06x', hl[prop]) if not color_usage[hex] then color_usage[hex] = { groups = {}, as = { fg = 0, bg = 0, sp = 0 } } end color_usage[hex].as[prop] = color_usage[hex].as[prop] + 1 color_usage[hex].groups[#color_usage[hex].groups + 1] = name .. '.' .. prop end end end print('=== Color Usage Analysis ===') print('') -- Sort by total usage local sorted = {} for hex, info in pairs(color_usage) do local total = info.as.fg + info.as.bg + info.as.sp sorted[#sorted + 1] = { hex = hex, info = info, total = total } end table.sort(sorted, function(a, b) return a.total > b.total end) local covered = 0 local uncovered = 0 local uncovered_colors = {} for _, entry in ipairs(sorted) do local hex = entry.hex local name = hex_to_name[hex] or 'UNKNOWN' local slot = name_to_slot[name] local status = slot and ('slot ' .. slot) or 'UNMAPPED' print(string.format('%-30s %-25s fg=%-3d bg=%-3d sp=%-3d total=%-3d %s', hex, name, entry.info.as.fg, entry.info.as.bg, entry.info.as.sp, entry.total, status)) if slot then covered = covered + entry.total else uncovered = uncovered + entry.total uncovered_colors[#uncovered_colors + 1] = { hex = hex, name = name, total = entry.total } end end print('') print(string.format('Covered by ANSI: %d references', covered)) print(string.format('Not in ANSI palette: %d references', uncovered)) print('') print('=== Unmapped colors ===') for _, c in ipairs(uncovered_colors) do print(string.format(' %-30s (%s) used %d times', c.hex, c.name, c.total)) end print('') print('=== Proposed indexed slot assignment ===') local next_slot = 16 for _, c in ipairs(uncovered_colors) do print(string.format(' indexed[%d] = %s (%s)', next_slot, c.hex, c.name)) next_slot = next_slot + 1 end -- Also check: can we reclaim slot 9? print('') print('=== Slot 9 reclaim ===') print('Slot 9 currently duplicates error (slot 1).') print('Can be reassigned to: ' .. uncovered_colors[1].name .. ' (' .. uncovered_colors[1].hex .. ')')