Add highlight info display under cursor

Implement a function to show highlight group and color
information in a floating window when the cursor is
positioned over text.
This commit is contained in:
Ray Elliott 2026-01-13 16:05:44 +00:00
parent 70d28cbb3f
commit 10f61ab939
2 changed files with 137 additions and 131 deletions

View File

@ -62,135 +62,5 @@ end, { desc = 'Git: Changed files to quickfix (with status)', silent = true })
-- Debug: Show highlight group and color under cursor -- Debug: Show highlight group and color under cursor
map('n', '<leader>hi', function() map('n', '<leader>hi', function()
local cursor_pos = vim.api.nvim_win_get_cursor(0) require('utils').show_highlight_info()
local row, col = cursor_pos[1] - 1, cursor_pos[2]
-- Get all highlight groups at cursor position
local ts_hl = vim.treesitter.get_captures_at_pos(0, row, col)
local synID = vim.fn.synID(row + 1, col + 1, 1)
local synName = vim.fn.synIDattr(synID, 'name')
local synTrans = vim.fn.synIDattr(vim.fn.synIDtrans(synID), 'name')
-- Helper to resolve highlight links
local function resolve_hl(name)
local hl = vim.api.nvim_get_hl(0, { name = name })
local max_depth = 10
local depth = 0
while hl.link and depth < max_depth do
name = hl.link
hl = vim.api.nvim_get_hl(0, { name = name })
depth = depth + 1
end
return hl, name
end
local lines = {
'=== Highlight Info Under Cursor ===',
'',
'Position: row=' .. row .. ' col=' .. col,
'',
}
-- TreeSitter captures
if #ts_hl > 0 then
table.insert(lines, 'TreeSitter Captures:')
for _, capture in ipairs(ts_hl) do
local cap_name = '@' .. capture.capture
local hl, resolved_name = resolve_hl(cap_name)
table.insert(lines, string.format(' %s', cap_name))
if resolved_name ~= cap_name then
table.insert(lines, string.format(' → resolves to: %s', resolved_name))
end
if hl.fg then
table.insert(lines, string.format(' fg: #%06x', hl.fg))
end
if hl.bg then
table.insert(lines, string.format(' bg: #%06x', hl.bg))
end
local styles = {}
if hl.bold then table.insert(styles, 'bold') end
if hl.italic then table.insert(styles, 'italic') end
if hl.underline then table.insert(styles, 'underline') end
if #styles > 0 then
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
end
end
table.insert(lines, '')
end
-- Syntax group
if synName ~= '' then
table.insert(lines, 'Syntax Group: ' .. synName)
if synTrans ~= synName and synTrans ~= '' then
table.insert(lines, 'Translates to: ' .. synTrans)
end
local hl, resolved_name = resolve_hl(synTrans ~= '' and synTrans or synName)
if hl.fg then
table.insert(lines, string.format(' fg: #%06x', hl.fg))
end
if hl.bg then
table.insert(lines, string.format(' bg: #%06x', hl.bg))
end
table.insert(lines, '')
end
-- Final applied highlight (use TreeSitter if available, otherwise syntax)
local final_hl_name = nil
if #ts_hl > 0 then
final_hl_name = '@' .. ts_hl[1].capture
elseif synTrans ~= '' then
final_hl_name = synTrans
elseif synName ~= '' then
final_hl_name = synName
end
if final_hl_name then
local final_hl, final_resolved = resolve_hl(final_hl_name)
table.insert(lines, 'Applied Highlight: ' .. final_resolved)
if final_hl.fg then
table.insert(lines, string.format(' fg: #%06x', final_hl.fg))
else
table.insert(lines, ' fg: NONE')
end
if final_hl.bg then
table.insert(lines, string.format(' bg: #%06x', final_hl.bg))
else
table.insert(lines, ' bg: NONE')
end
local styles = {}
if final_hl.bold then table.insert(styles, 'bold') end
if final_hl.italic then table.insert(styles, 'italic') end
if final_hl.underline then table.insert(styles, 'underline') end
if final_hl.undercurl then table.insert(styles, 'undercurl') end
if #styles > 0 then
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
end
end
-- Show in a floating window
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
local width = 0
for _, line in ipairs(lines) do
width = math.max(width, #line)
end
width = math.min(width + 2, vim.o.columns - 4)
local height = #lines
local opts = {
relative = 'cursor',
width = width,
height = height,
row = 1,
col = 0,
style = 'minimal',
border = 'rounded',
}
vim.api.nvim_open_win(buf, false, opts)
end, { desc = 'Debug: Show highlight group and color under cursor', silent = true }) end, { desc = 'Debug: Show highlight group and color under cursor', silent = true })

View File

@ -68,6 +68,142 @@ function M.git_changed_files()
return qf_list return qf_list
end end
-- Show highlight group and color information under cursor
-- Returns nothing, displays results in a floating window
function M.show_highlight_info()
local cursor_pos = vim.api.nvim_win_get_cursor(0)
local row, col = cursor_pos[1] - 1, cursor_pos[2]
-- Get all highlight groups at cursor position
local ts_hl = vim.treesitter.get_captures_at_pos(0, row, col)
local synID = vim.fn.synID(row + 1, col + 1, 1)
local synName = vim.fn.synIDattr(synID, 'name')
local synTrans = vim.fn.synIDattr(vim.fn.synIDtrans(synID), 'name')
-- Helper to resolve highlight links
local function resolve_hl(name)
local hl = vim.api.nvim_get_hl(0, { name = name })
local max_depth = 10
local depth = 0
while hl.link and depth < max_depth do
name = hl.link
hl = vim.api.nvim_get_hl(0, { name = name })
depth = depth + 1
end
return hl, name
end
local lines = {
'=== Highlight Info Under Cursor ===',
'',
'Position: row=' .. row .. ' col=' .. col,
'',
}
-- TreeSitter captures
if #ts_hl > 0 then
table.insert(lines, 'TreeSitter Captures:')
for _, capture in ipairs(ts_hl) do
local cap_name = '@' .. capture.capture
local hl, resolved_name = resolve_hl(cap_name)
table.insert(lines, string.format(' %s', cap_name))
if resolved_name ~= cap_name then
table.insert(lines, string.format(' → resolves to: %s', resolved_name))
end
if hl.fg then
table.insert(lines, string.format(' fg: #%06x', hl.fg))
end
if hl.bg then
table.insert(lines, string.format(' bg: #%06x', hl.bg))
end
local styles = {}
if hl.bold then table.insert(styles, 'bold') end
if hl.italic then table.insert(styles, 'italic') end
if hl.underline then table.insert(styles, 'underline') end
if #styles > 0 then
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
end
end
table.insert(lines, '')
end
-- Syntax group
if synName ~= '' then
table.insert(lines, 'Syntax Group: ' .. synName)
if synTrans ~= synName and synTrans ~= '' then
table.insert(lines, 'Translates to: ' .. synTrans)
end
local hl, resolved_name = resolve_hl(synTrans ~= '' and synTrans or synName)
if hl.fg then
table.insert(lines, string.format(' fg: #%06x', hl.fg))
end
if hl.bg then
table.insert(lines, string.format(' bg: #%06x', hl.bg))
end
table.insert(lines, '')
end
-- Final applied highlight (use TreeSitter if available, otherwise syntax)
local final_hl_name = nil
if #ts_hl > 0 then
final_hl_name = '@' .. ts_hl[1].capture
elseif synTrans ~= '' then
final_hl_name = synTrans
elseif synName ~= '' then
final_hl_name = synName
end
if final_hl_name then
local final_hl, final_resolved = resolve_hl(final_hl_name)
table.insert(lines, 'Applied Highlight: ' .. final_resolved)
if final_hl.fg then
table.insert(lines, string.format(' fg: #%06x', final_hl.fg))
else
table.insert(lines, ' fg: NONE')
end
if final_hl.bg then
table.insert(lines, string.format(' bg: #%06x', final_hl.bg))
else
table.insert(lines, ' bg: NONE')
end
local styles = {}
if final_hl.bold then table.insert(styles, 'bold') end
if final_hl.italic then table.insert(styles, 'italic') end
if final_hl.underline then table.insert(styles, 'underline') end
if final_hl.undercurl then table.insert(styles, 'undercurl') end
if #styles > 0 then
table.insert(lines, ' style: ' .. table.concat(styles, ', '))
end
end
-- Show in a floating window
local buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines)
local width = 0
for _, line in ipairs(lines) do
width = math.max(width, #line)
end
width = math.min(width + 2, vim.o.columns - 4)
local height = #lines
local opts = {
relative = 'cursor',
width = width,
height = height,
row = 1,
col = 0,
style = 'minimal',
border = 'rounded',
}
vim.api.nvim_open_win(buf, false, opts)
end
-- Custom tabline function -- Custom tabline function
-- Shows configurable number of full parent directories, shortens the rest -- Shows configurable number of full parent directories, shortens the rest
function M.custom_tabline() function M.custom_tabline()