diff --git a/doc/fugitive-ts.nvim.txt b/doc/fugitive-ts.nvim.txt index a825909..f91fb09 100644 --- a/doc/fugitive-ts.nvim.txt +++ b/doc/fugitive-ts.nvim.txt @@ -34,6 +34,10 @@ SETUP *fugitive-ts-setup* -- Debounce delay in ms (default: 50) debounce_ms = 50, + + -- Max lines per hunk before skipping treesitter (default: 500) + -- Prevents lag on large diffs + max_lines_per_hunk = 500, }) < diff --git a/lua/fugitive-ts/highlight.lua b/lua/fugitive-ts/highlight.lua index c77a3fa..ea292d0 100644 --- a/lua/fugitive-ts/highlight.lua +++ b/lua/fugitive-ts/highlight.lua @@ -10,13 +10,27 @@ end ---@param bufnr integer ---@param ns integer ---@param hunk fugitive-ts.Hunk +---@param max_lines integer ---@param debug? boolean -function M.highlight_hunk(bufnr, ns, hunk, debug) +function M.highlight_hunk(bufnr, ns, hunk, max_lines, debug) local lang = hunk.lang if not lang then return end + if #hunk.lines > max_lines then + if debug then + dbg( + 'skipping hunk %s:%d (%d lines > %d max)', + hunk.filename, + hunk.start_line, + #hunk.lines, + max_lines + ) + end + return + end + ---@type string[] local code_lines = {} for _, line in ipairs(hunk.lines) do @@ -52,6 +66,18 @@ function M.highlight_hunk(bufnr, ns, hunk, debug) return end + 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 + pcall(vim.api.nvim_buf_set_extmark, bufnr, ns, buf_line, 1, { + end_col = line_len, + hl_group = 'Normal', + priority = 199, + }) + end + end + local extmark_count = 0 for id, node, _ in query:iter_captures(trees[1]:root(), code) do local capture_name = '@' .. query.captures[id] diff --git a/lua/fugitive-ts/init.lua b/lua/fugitive-ts/init.lua index 8bd4977..e6de719 100644 --- a/lua/fugitive-ts/init.lua +++ b/lua/fugitive-ts/init.lua @@ -3,6 +3,7 @@ ---@field debug boolean ---@field languages table ---@field debounce_ms integer +---@field max_lines_per_hunk integer ---@class fugitive-ts ---@field attach fun(bufnr?: integer) @@ -21,6 +22,7 @@ local default_config = { debug = false, languages = {}, debounce_ms = 50, + max_lines_per_hunk = 500, } ---@type fugitive-ts.Config @@ -54,7 +56,7 @@ local function highlight_buffer(bufnr) local hunks = parser.parse_buffer(bufnr, config.languages, config.debug) dbg('found %d hunks in buffer %d', #hunks, bufnr) for _, hunk in ipairs(hunks) do - highlight.highlight_hunk(bufnr, ns, hunk, config.debug) + highlight.highlight_hunk(bufnr, ns, hunk, config.max_lines_per_hunk, config.debug) end end @@ -101,6 +103,14 @@ function M.attach(bufnr) callback = debounced, }) + vim.api.nvim_create_autocmd('Syntax', { + buffer = bufnr, + callback = function() + dbg('syntax event, re-highlighting buffer %d', bufnr) + highlight_buffer(bufnr) + end, + }) + vim.api.nvim_create_autocmd('BufWipeout', { buffer = bufnr, callback = function()