perf(git): bounded upward search in show.diff_section
This commit is contained in:
+17
-16
@@ -26,22 +26,21 @@ local function context()
|
|||||||
return { worktree = worktree, ref = ref, parent_ref = vim.b.git_parent_ref }
|
return { worktree = worktree, ref = ref, parent_ref = vim.b.git_parent_ref }
|
||||||
end
|
end
|
||||||
|
|
||||||
---Walk upward from the cursor to the enclosing `diff --git` line and parse
|
---Find the enclosing `diff --git` line and parse the section's pre/post
|
||||||
---the section's pre/post paths plus the pre/post blob SHAs from the `index`
|
---paths plus the pre/post blob SHAs from the `index` line.
|
||||||
---line.
|
---
|
||||||
---@param cursor_lnum integer 1-indexed
|
---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?
|
---@return ow.Git.DiffSection?
|
||||||
local function diff_section(cursor_lnum)
|
local function diff_section()
|
||||||
local lines = vim.api.nvim_buf_get_lines(0, 0, cursor_lnum, false)
|
local diff_lnum = vim.fn.search("^diff --git ", "bcnW")
|
||||||
local diff_lnum, diff_line
|
if diff_lnum == 0 then
|
||||||
for i = #lines, 1, -1 do
|
return nil
|
||||||
if lines[i]:match("^diff %-%-git ") then
|
|
||||||
diff_lnum = i
|
|
||||||
diff_line = lines[i]
|
|
||||||
break
|
|
||||||
end
|
end
|
||||||
end
|
local diff_line =
|
||||||
if not diff_lnum or not diff_line then
|
vim.api.nvim_buf_get_lines(0, diff_lnum - 1, diff_lnum, false)[1]
|
||||||
|
if not diff_line then
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
local pre_path, post_path = diff_line:match("^diff %-%-git a/(.-) b/(.+)$")
|
local pre_path, post_path = diff_line:match("^diff %-%-git a/(.-) b/(.+)$")
|
||||||
@@ -49,6 +48,9 @@ local function diff_section(cursor_lnum)
|
|||||||
return nil
|
return nil
|
||||||
end
|
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 =
|
local header =
|
||||||
vim.api.nvim_buf_get_lines(0, diff_lnum, diff_lnum + 20, false)
|
vim.api.nvim_buf_get_lines(0, diff_lnum, diff_lnum + 20, false)
|
||||||
local pre_blob, post_blob
|
local pre_blob, post_blob
|
||||||
@@ -165,8 +167,7 @@ function M.open_at_cursor()
|
|||||||
if not ctx then
|
if not ctx then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local cursor_lnum = vim.api.nvim_win_get_cursor(0)[1]
|
local section = diff_section()
|
||||||
local section = diff_section(cursor_lnum)
|
|
||||||
if not section then
|
if not section then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user