fix(highlight): use hunk body as context for header treesitter parsing
Problem: the header context string (e.g. "function M.setup()") was parsed in isolation by treesitter, which couldn't recognize "function" as @keyword.function because the snippet is an incomplete definition with no body or "end". Solution: append the already-built new_code lines as trailing context when parsing the header string, giving treesitter a complete function definition. Filter captures to row 0 only so body-line captures don't produce extmarks on the header line.
This commit is contained in:
parent
3b2e0de2a7
commit
38220ab368
2 changed files with 68 additions and 18 deletions
|
|
@ -41,9 +41,15 @@ local PRIORITY_CHAR_BG = 201
|
|||
---@param col_offset integer
|
||||
---@param text string
|
||||
---@param lang string
|
||||
---@param context_lines? string[]
|
||||
---@return integer
|
||||
local function highlight_text(bufnr, ns, hunk, col_offset, text, lang)
|
||||
local ok, parser_obj = pcall(vim.treesitter.get_string_parser, text, lang)
|
||||
local function highlight_text(bufnr, ns, hunk, col_offset, text, lang, context_lines)
|
||||
local parse_text = text
|
||||
if context_lines and #context_lines > 0 then
|
||||
parse_text = text .. '\n' .. table.concat(context_lines, '\n')
|
||||
end
|
||||
|
||||
local ok, parser_obj = pcall(vim.treesitter.get_string_parser, parse_text, lang)
|
||||
if not ok or not parser_obj then
|
||||
return 0
|
||||
end
|
||||
|
|
@ -61,24 +67,27 @@ local function highlight_text(bufnr, ns, hunk, col_offset, text, lang)
|
|||
local extmark_count = 0
|
||||
local header_line = hunk.start_line - 1
|
||||
|
||||
for id, node, metadata in query:iter_captures(trees[1]:root(), text) do
|
||||
local capture_name = '@' .. query.captures[id] .. '.' .. lang
|
||||
for id, node, metadata in query:iter_captures(trees[1]:root(), parse_text) do
|
||||
local sr, sc, er, ec = node:range()
|
||||
if sr == 0 then
|
||||
er = 0
|
||||
local capture_name = '@' .. query.captures[id] .. '.' .. lang
|
||||
|
||||
local buf_sr = header_line + sr
|
||||
local buf_er = header_line + er
|
||||
local buf_sc = col_offset + sc
|
||||
local buf_ec = col_offset + ec
|
||||
local buf_sr = header_line
|
||||
local buf_er = header_line
|
||||
local buf_sc = col_offset + sc
|
||||
local buf_ec = col_offset + ec
|
||||
|
||||
local priority = lang == 'diff' and (tonumber(metadata.priority) or 100) or PRIORITY_SYNTAX
|
||||
local priority = lang == 'diff' and (tonumber(metadata.priority) or 100) or PRIORITY_SYNTAX
|
||||
|
||||
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_sr, buf_sc, {
|
||||
end_row = buf_er,
|
||||
end_col = buf_ec,
|
||||
hl_group = capture_name,
|
||||
priority = priority,
|
||||
})
|
||||
extmark_count = extmark_count + 1
|
||||
pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_sr, buf_sc, {
|
||||
end_row = buf_er,
|
||||
end_col = buf_ec,
|
||||
hl_group = capture_name,
|
||||
priority = priority,
|
||||
})
|
||||
extmark_count = extmark_count + 1
|
||||
end
|
||||
end
|
||||
|
||||
return extmark_count
|
||||
|
|
@ -360,8 +369,15 @@ function M.highlight_hunk(bufnr, ns, hunk, opts)
|
|||
hl_group = 'DiffsClear',
|
||||
priority = PRIORITY_CLEAR,
|
||||
})
|
||||
local header_extmarks =
|
||||
highlight_text(bufnr, ns, hunk, hunk.header_context_col, hunk.header_context, hunk.lang)
|
||||
local header_extmarks = highlight_text(
|
||||
bufnr,
|
||||
ns,
|
||||
hunk,
|
||||
hunk.header_context_col,
|
||||
hunk.header_context,
|
||||
hunk.lang,
|
||||
new_code
|
||||
)
|
||||
if header_extmarks > 0 then
|
||||
dbg('header %s:%d applied %d extmarks', hunk.filename, hunk.start_line, header_extmarks)
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue