feat(hl): highlight icons

This commit is contained in:
Barrett Ruth 2026-03-02 19:40:26 -05:00
parent 4335fb8596
commit 7a655c9919
Signed by: barrett
GPG key ID: A6C96C9349D2FC81
5 changed files with 130 additions and 3 deletions

71
lua/nonicons/colors.lua Normal file
View file

@ -0,0 +1,71 @@
---@type table<string, { [1]: string, [2]: integer }>
local M = {
['angular'] = { '#e23237', 161 },
['babel'] = { '#f9dc3e', 185 },
['book'] = { '#a8b1c7', 146 },
['c'] = { '#599eff', 111 },
['c-plusplus'] = { '#f34b7d', 204 },
['c-sharp'] = { '#68217a', 55 },
['code'] = { '#a9b7c6', 145 },
['css'] = { '#563d7c', 60 },
['dart'] = { '#00b4ab', 37 },
['database'] = { '#dad8d8', 188 },
['diff'] = { '#41535b', 59 },
['docker'] = { '#0db7ed', 39 },
['elixir'] = { '#a074c4', 140 },
['elm'] = { '#60b5cc', 74 },
['eslint'] = { '#4b32c3', 56 },
['file'] = { '#6d8086', 66 },
['file-binary'] = { '#9f0500', 124 },
['file-zip'] = { '#eca517', 214 },
['gear'] = { '#6d8086', 66 },
['git-branch'] = { '#f14e32', 196 },
['git-commit'] = { '#f14e32', 196 },
['globe'] = { '#519aba', 74 },
['go'] = { '#00add8', 38 },
['graphql'] = { '#e535ab', 199 },
['html'] = { '#e34c26', 166 },
['image'] = { '#a074c4', 140 },
['java'] = { '#cc3e44', 167 },
['javascript'] = { '#f1e05a', 185 },
['json'] = { '#fbc02d', 220 },
['key'] = { '#e6c419', 220 },
['kotlin'] = { '#7f52ff', 99 },
['law'] = { '#cbcb41', 185 },
['lock'] = { '#bbbbbb', 250 },
['log'] = { '#afb42b', 142 },
['logo-github'] = { '#f0eff1', 255 },
['lua'] = { '#51a0cf', 74 },
['markdown'] = { '#519aba', 74 },
['next'] = { '#a9b7c6', 145 },
['nginx'] = { '#009639', 28 },
['npm'] = { '#cb3837', 160 },
['package'] = { '#cb3837', 160 },
['perl'] = { '#39457e', 61 },
['php'] = { '#4f5d95', 61 },
['play'] = { '#e37933', 208 },
['prettier'] = { '#56b3b4', 73 },
['python'] = { '#3776ab', 68 },
['r'] = { '#276dc3', 68 },
['react'] = { '#61dafb', 75 },
['rss'] = { '#f26522', 208 },
['ruby'] = { '#cc342d', 160 },
['rust'] = { '#dea584', 180 },
['scala'] = { '#cc3e44', 167 },
['server'] = { '#6d8086', 66 },
['shield'] = { '#43853d', 35 },
['svelte'] = { '#ff3e00', 202 },
['swift'] = { '#f05138', 203 },
['terminal'] = { '#4d4d4d', 239 },
['terraform'] = { '#844fba', 135 },
['tmux'] = { '#1bb91f', 34 },
['toml'] = { '#9c4221', 130 },
['typescript'] = { '#3178c6', 68 },
['typography'] = { '#e34c26', 166 },
['vim'] = { '#019833', 28 },
['vue'] = { '#41b883', 35 },
['yaml'] = { '#cb171e', 160 },
['yarn'] = { '#2c8ebb', 68 },
}
return M

View file

@ -7,7 +7,7 @@ function M.check()
if ok and devicons then if ok and devicons then
vim.health.ok('nvim-web-devicons available') vim.health.ok('nvim-web-devicons available')
else else
vim.health.error('nvim-web-devicons not found') vim.health.info('nvim-web-devicons not found (using built-in highlights)')
end end
local result = vim.fn.system({ 'fc-list', ':family=nonicons' }) local result = vim.fn.system({ 'fc-list', ':family=nonicons' })

View file

@ -52,6 +52,10 @@ return function()
string.format(' %-4s %-28s %-7s %s', 'ICON', 'NAME', 'CODE', 'MAPPED FROM') string.format(' %-4s %-28s %-7s %s', 'ICON', 'NAME', 'CODE', 'MAPPED FROM')
lines[#lines + 1] = string.rep('-', 72) lines[#lines + 1] = string.rep('-', 72)
local highlights = require('nonicons.highlights')
local icon_line_start = #lines
local icon_glyphs = {} ---@type string[]
for _, name in ipairs(icon_names) do for _, name in ipairs(icon_names) do
local sources = {} ---@type string[] local sources = {} ---@type string[]
if ext_by_icon[name] then if ext_by_icon[name] then
@ -70,9 +74,11 @@ return function()
end end
end end
local glyph = char(name)
local src_str = #sources > 0 and table.concat(sources, ', ') or '' local src_str = #sources > 0 and table.concat(sources, ', ') or ''
lines[#lines + 1] = lines[#lines + 1] =
string.format(' %s %-28s U+%04X %s', char(name), name, mapping[name], src_str) string.format(' %s %-28s U+%04X %s', glyph, name, mapping[name], src_str)
icon_glyphs[#icon_glyphs + 1] = glyph
end end
lines[#lines + 1] = '' lines[#lines + 1] = ''
@ -80,6 +86,14 @@ return function()
local buf = vim.api.nvim_create_buf(false, true) local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
for i, name in ipairs(icon_names) do
local hl = highlights.get(name)
local col_start = 2
local col_end = col_start + #icon_glyphs[i]
vim.api.nvim_buf_add_highlight(buf, -1, hl, icon_line_start + i - 1, col_start, col_end)
end
vim.bo[buf].modifiable = false vim.bo[buf].modifiable = false
vim.bo[buf].buftype = 'nofile' vim.bo[buf].buftype = 'nofile'
vim.bo[buf].bufhidden = 'wipe' vim.bo[buf].bufhidden = 'wipe'

View file

@ -0,0 +1,37 @@
local colors = require('nonicons.colors')
local M = {}
---@param icon_name string
---@return string
local function to_hl_group(icon_name)
local parts = {}
for part in icon_name:gmatch('[^-]+') do
parts[#parts + 1] = part:sub(1, 1):upper() .. part:sub(2)
end
return 'Nonicons' .. table.concat(parts)
end
local function apply()
for name, data in pairs(colors) do
vim.api.nvim_set_hl(0, to_hl_group(name), { fg = data[1], ctermfg = data[2] })
end
end
function M.setup()
apply()
local group = vim.api.nvim_create_augroup('NoniconsHighlights', { clear = true })
vim.api.nvim_create_autocmd('ColorScheme', {
group = group,
callback = apply,
})
end
---@param icon_name string
---@return string hl_group
function M.get(icon_name)
return to_hl_group(icon_name)
end
return M

View file

@ -29,15 +29,18 @@ M.mapping = require('nonicons.mapping')
---@param name string Icon name ---@param name string Icon name
---@return string? glyph ---@return string? glyph
---@return string? hl_group
function M.get(name) function M.get(name)
local code = M.mapping[name] local code = M.mapping[name]
if code then if code then
return vim.fn.nr2char(code) local hl = require('nonicons.highlights').get(name)
return vim.fn.nr2char(code), hl
end end
end end
function M.apply() function M.apply()
ensure_initialized() ensure_initialized()
require('nonicons.highlights').setup()
if config.override then if config.override then
require('nonicons.override').apply() require('nonicons.override').apply()
end end
@ -46,6 +49,7 @@ end
---@param name string? Filename (e.g. `'init.lua'`) ---@param name string? Filename (e.g. `'init.lua'`)
---@param ext string? File extension (e.g. `'lua'`) ---@param ext string? File extension (e.g. `'lua'`)
---@return string? glyph ---@return string? glyph
---@return string? hl_group
function M.get_icon(name, ext) function M.get_icon(name, ext)
local key = require('nonicons.resolve').resolve_name(name, ext) local key = require('nonicons.resolve').resolve_name(name, ext)
if key then if key then
@ -55,6 +59,7 @@ end
---@param ft string Vim filetype ---@param ft string Vim filetype
---@return string? glyph ---@return string? glyph
---@return string? hl_group
function M.get_icon_by_filetype(ft) function M.get_icon_by_filetype(ft)
local key = require('nonicons.resolve').resolve_filetype(ft) local key = require('nonicons.resolve').resolve_filetype(ft)
if key then if key then