perf(git): bounded upward search in show.diff_section

This commit is contained in:
2026-04-27 14:21:30 +02:00
parent 2ef9cb7c9e
commit 15909e3ca1
+17 -16
View File
@@ -26,22 +26,21 @@ local function context()
return { worktree = worktree, ref = ref, parent_ref = vim.b.git_parent_ref }
end
---Walk upward from the cursor to the enclosing `diff --git` line and parse
---the section's pre/post paths plus the pre/post blob SHAs from the `index`
---line.
---@param cursor_lnum integer 1-indexed
---Find the enclosing `diff --git` line and parse the section's pre/post
---paths plus the pre/post blob SHAs from the `index` line.
---
---Uses `vim.fn.search('bcnW')` (backward, accept cursor pos, no move, no
---wrap) so a giant `git show <merge>` buffer doesn't pay an O(cursor_lnum)
---array allocation on every <CR>.
---@return ow.Git.DiffSection?
local function diff_section(cursor_lnum)
local lines = vim.api.nvim_buf_get_lines(0, 0, cursor_lnum, false)
local diff_lnum, diff_line
for i = #lines, 1, -1 do
if lines[i]:match("^diff %-%-git ") then
diff_lnum = i
diff_line = lines[i]
break
end
local function diff_section()
local diff_lnum = vim.fn.search("^diff --git ", "bcnW")
if diff_lnum == 0 then
return nil
end
if not diff_lnum or not diff_line then
local diff_line =
vim.api.nvim_buf_get_lines(0, diff_lnum - 1, diff_lnum, false)[1]
if not diff_line then
return nil
end
local pre_path, post_path = diff_line:match("^diff %-%-git a/(.-) b/(.+)$")
@@ -49,6 +48,9 @@ local function diff_section(cursor_lnum)
return nil
end
-- Header lines (mode/index/oldfile/newfile/etc) sit between the
-- `diff --git` line and the first `@@` hunk; cap the read at 20 to
-- bound work even for unusual diff headers.
local header =
vim.api.nvim_buf_get_lines(0, diff_lnum, diff_lnum + 20, false)
local pre_blob, post_blob
@@ -165,8 +167,7 @@ function M.open_at_cursor()
if not ctx then
return false
end
local cursor_lnum = vim.api.nvim_win_get_cursor(0)[1]
local section = diff_section(cursor_lnum)
local section = diff_section()
if not section then
return false
end