feat: highlights

This commit is contained in:
Barrett Ruth 2026-02-01 23:17:20 -06:00
parent d5fb6d36ef
commit 00bf84cb05
5 changed files with 437 additions and 41 deletions

View file

@ -55,26 +55,30 @@ local function highlight_text(bufnr, ns, hunk, col_offset, text, lang, debug)
return extmark_count
end
---@class fugitive-ts.HunkOpts
---@field max_lines integer
---@field conceal_prefixes boolean
---@field highlights fugitive-ts.Highlights
---@field debug boolean
---@param bufnr integer
---@param ns integer
---@param hunk fugitive-ts.Hunk
---@param max_lines integer
---@param highlight_headers boolean
---@param debug? boolean
function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
---@param opts fugitive-ts.HunkOpts
function M.highlight_hunk(bufnr, ns, hunk, opts)
local lang = hunk.lang
if not lang then
return
end
if #hunk.lines > max_lines then
if debug then
if #hunk.lines > opts.max_lines then
if opts.debug then
dbg(
'skipping hunk %s:%d (%d lines > %d max)',
hunk.filename,
hunk.start_line,
#hunk.lines,
max_lines
opts.max_lines
)
end
return
@ -93,7 +97,7 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
local ok, parser_obj = pcall(vim.treesitter.get_string_parser, code, lang)
if not ok or not parser_obj then
if debug then
if opts.debug then
dbg('failed to create parser for lang: %s', lang)
end
return
@ -101,7 +105,7 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
local trees = parser_obj:parse()
if not trees or #trees == 0 then
if debug then
if opts.debug then
dbg('parse returned no trees for lang: %s', lang)
end
return
@ -109,22 +113,29 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
local query = vim.treesitter.query.get(lang, 'highlights')
if not query then
if debug then
if opts.debug then
dbg('no highlights query for lang: %s', lang)
end
return
end
if highlight_headers and hunk.header_context and hunk.header_context_col then
if opts.highlights.headers and hunk.header_context and hunk.header_context_col then
local header_line = hunk.start_line - 1
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, header_line, hunk.header_context_col, {
end_col = hunk.header_context_col + #hunk.header_context,
hl_group = 'Normal',
priority = 199,
})
local header_extmarks =
highlight_text(bufnr, ns, hunk, hunk.header_context_col, hunk.header_context, lang, debug)
if debug and header_extmarks > 0 then
local header_extmarks = highlight_text(
bufnr,
ns,
hunk,
hunk.header_context_col,
hunk.header_context,
lang,
opts.debug
)
if opts.debug and header_extmarks > 0 then
dbg('header %s:%d applied %d extmarks', hunk.filename, hunk.start_line, header_extmarks)
end
end
@ -132,7 +143,28 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
for i, line in ipairs(hunk.lines) do
local buf_line = hunk.start_line + i - 1
local line_len = #line
if line_len > 1 then
local prefix = line:sub(1, 1)
if opts.conceal_prefixes then
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, 0, {
end_col = 1,
conceal = '',
})
end
if opts.highlights.background and (prefix == '+' or prefix == '-') then
local line_hl = prefix == '+' and 'DiffAdd' or 'DiffDelete'
local extmark_opts = {
line_hl_group = line_hl,
priority = 198,
}
if opts.highlights.linenr then
extmark_opts.number_hl_group = line_hl
end
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, 0, extmark_opts)
end
if line_len > 1 and opts.highlights.treesitter then
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, 1, {
end_col = line_len,
hl_group = 'Normal',
@ -141,6 +173,10 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
end
end
if not opts.highlights.treesitter then
return
end
local extmark_count = 0
for id, node, _ in query:iter_captures(trees[1]:root(), code) do
local capture_name = '@' .. query.captures[id]
@ -160,7 +196,7 @@ function M.highlight_hunk(bufnr, ns, hunk, max_lines, highlight_headers, debug)
extmark_count = extmark_count + 1
end
if debug then
if opts.debug then
dbg('hunk %s:%d applied %d extmarks', hunk.filename, hunk.start_line, extmark_count)
end
end