feat(highlight): wire highlights.context config into treesitter pipeline
Problem: `highlights.context.enabled` and `highlights.context.lines` were defined, validated, and range-checked but never read during highlighting. Hunks inside incomplete constructs (e.g., a table literal or function body whose opening is beyond the hunk's own context lines) parsed incorrectly. Solution: `compute_hunk_context` reads the working tree file using the hunk's `@@ +start,count @@` line numbers to collect surrounding code. Files are read once and cached across hunks. `highlight_treesitter` accepts an optional context parameter that prepends/appends context lines to the parse string, offsetting capture rows so extmarks only land on hunk lines.
This commit is contained in:
parent
e1d3b81607
commit
70e623fcce
5 changed files with 534 additions and 17 deletions
|
|
@ -67,6 +67,10 @@ end
|
|||
---@field defer_vim_syntax? boolean
|
||||
---@field syntax_only? boolean
|
||||
|
||||
---@class diffs.TSContext
|
||||
---@field before string[]?
|
||||
---@field after string[]?
|
||||
|
||||
---@param bufnr integer
|
||||
---@param ns integer
|
||||
---@param code_lines string[]
|
||||
|
|
@ -76,6 +80,7 @@ end
|
|||
---@param covered_lines? table<integer, true>
|
||||
---@param priorities diffs.PrioritiesConfig
|
||||
---@param force_high_priority? boolean
|
||||
---@param context? diffs.TSContext
|
||||
---@return integer
|
||||
local function highlight_treesitter(
|
||||
bufnr,
|
||||
|
|
@ -86,9 +91,34 @@ local function highlight_treesitter(
|
|||
col_offset,
|
||||
covered_lines,
|
||||
priorities,
|
||||
force_high_priority
|
||||
force_high_priority,
|
||||
context
|
||||
)
|
||||
local code = table.concat(code_lines, '\n')
|
||||
local prefix_count = 0
|
||||
local parse_lines = code_lines
|
||||
if context then
|
||||
local before = context.before
|
||||
local after = context.after
|
||||
if (before and #before > 0) or (after and #after > 0) then
|
||||
parse_lines = {}
|
||||
if before then
|
||||
prefix_count = #before
|
||||
for _, l in ipairs(before) do
|
||||
parse_lines[#parse_lines + 1] = l
|
||||
end
|
||||
end
|
||||
for _, l in ipairs(code_lines) do
|
||||
parse_lines[#parse_lines + 1] = l
|
||||
end
|
||||
if after then
|
||||
for _, l in ipairs(after) do
|
||||
parse_lines[#parse_lines + 1] = l
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local code = table.concat(parse_lines, '\n')
|
||||
if code == '' then
|
||||
return 0
|
||||
end
|
||||
|
|
@ -118,6 +148,8 @@ local function highlight_treesitter(
|
|||
if capture ~= 'spell' and capture ~= 'nospell' then
|
||||
local capture_name = '@' .. capture .. '.' .. tree_lang
|
||||
local sr, sc, er, ec = node:range()
|
||||
sr = sr - prefix_count
|
||||
er = er - prefix_count
|
||||
|
||||
local buf_sr = line_map[sr]
|
||||
if buf_sr then
|
||||
|
|
@ -329,10 +361,36 @@ function M.highlight_hunk(bufnr, ns, hunk, opts)
|
|||
end
|
||||
end
|
||||
|
||||
extmark_count =
|
||||
highlight_treesitter(bufnr, ns, new_code, hunk.lang, new_map, pw + qw, covered_lines, p)
|
||||
local ts_context = nil
|
||||
if opts.highlights.context.enabled and (hunk.context_before or hunk.context_after) then
|
||||
ts_context = { before = hunk.context_before, after = hunk.context_after }
|
||||
end
|
||||
|
||||
extmark_count = highlight_treesitter(
|
||||
bufnr,
|
||||
ns,
|
||||
new_code,
|
||||
hunk.lang,
|
||||
new_map,
|
||||
pw + qw,
|
||||
covered_lines,
|
||||
p,
|
||||
nil,
|
||||
ts_context
|
||||
)
|
||||
extmark_count = extmark_count
|
||||
+ highlight_treesitter(bufnr, ns, old_code, hunk.lang, old_map, pw + qw, covered_lines, p)
|
||||
+ highlight_treesitter(
|
||||
bufnr,
|
||||
ns,
|
||||
old_code,
|
||||
hunk.lang,
|
||||
old_map,
|
||||
pw + qw,
|
||||
covered_lines,
|
||||
p,
|
||||
nil,
|
||||
ts_context
|
||||
)
|
||||
|
||||
if hunk.header_context and hunk.header_context_col then
|
||||
local header_extmarks = highlight_text(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue