perf(git): stash sidebar window in state
This commit is contained in:
+34
-15
@@ -32,6 +32,7 @@ local SIDEBAR_WIDTH = 50
|
||||
---@field gitdir string
|
||||
---@field worktree string
|
||||
---@field lines table<integer, ow.Git.StatusEntry>
|
||||
---@field sidebar_win integer?
|
||||
---@field diff_left_win integer?
|
||||
---@field diff_right_win integer?
|
||||
---@field user_aucmd integer?
|
||||
@@ -44,6 +45,8 @@ local group =
|
||||
vim.api.nvim_create_augroup("ow.git.status_win", { clear = false })
|
||||
local ns = vim.api.nvim_create_namespace("ow.git.status_win")
|
||||
|
||||
---Find the sidebar window in the current tabpage by filetype. Used as a
|
||||
---fallback when we don't have a `StatusState` handy (e.g. M.toggle).
|
||||
---@return integer? win
|
||||
---@return integer? bufnr
|
||||
local function find_sidebar()
|
||||
@@ -55,6 +58,20 @@ local function find_sidebar()
|
||||
end
|
||||
end
|
||||
|
||||
---Return the sidebar window stashed on `s`, validating that it's still
|
||||
---live. Falls back to `find_sidebar` if the stashed handle is gone.
|
||||
---@param s ow.Git.StatusState
|
||||
---@return integer?
|
||||
local function sidebar_win_for(s)
|
||||
local win = s.sidebar_win
|
||||
if win and vim.api.nvim_win_is_valid(win) then
|
||||
return win
|
||||
end
|
||||
win = find_sidebar()
|
||||
s.sidebar_win = win
|
||||
return win
|
||||
end
|
||||
|
||||
---@param entry ow.Git.StatusEntry
|
||||
---@return string?
|
||||
local function entry_code(entry)
|
||||
@@ -325,15 +342,13 @@ local function refresh(bufnr)
|
||||
end
|
||||
|
||||
local saved_path, saved_sha
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
||||
local lnum = vim.api.nvim_win_get_cursor(win)[1]
|
||||
local entry = s.lines[lnum]
|
||||
if entry then
|
||||
saved_path = entry.path
|
||||
saved_sha = entry.sha
|
||||
end
|
||||
break
|
||||
local sidebar_win = sidebar_win_for(s)
|
||||
if sidebar_win then
|
||||
local lnum = vim.api.nvim_win_get_cursor(sidebar_win)[1]
|
||||
local entry = s.lines[lnum]
|
||||
if entry then
|
||||
saved_path = entry.path
|
||||
saved_sha = entry.sha
|
||||
end
|
||||
end
|
||||
|
||||
@@ -350,10 +365,9 @@ local function refresh(bufnr)
|
||||
(saved_path and entry.path == saved_path)
|
||||
or (saved_sha and entry.sha == saved_sha)
|
||||
then
|
||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
||||
pcall(vim.api.nvim_win_set_cursor, win, { lnum, 0 })
|
||||
end
|
||||
local win = sidebar_win_for(s)
|
||||
if win then
|
||||
pcall(vim.api.nvim_win_set_cursor, win, { lnum, 0 })
|
||||
end
|
||||
break
|
||||
end
|
||||
@@ -554,7 +568,7 @@ local function show_diff(s, entry, focus_left)
|
||||
return
|
||||
end
|
||||
---@cast entry ow.Git.FileEntry
|
||||
local sidebar_win = find_sidebar()
|
||||
local sidebar_win = sidebar_win_for(s)
|
||||
if not sidebar_win then
|
||||
return
|
||||
end
|
||||
@@ -788,7 +802,12 @@ local function open(worktree)
|
||||
vim.wo[win].winfixwidth = true
|
||||
vim.api.nvim_win_set_width(win, SIDEBAR_WIDTH)
|
||||
|
||||
state[bufnr] = { gitdir = gitdir, worktree = worktree, lines = {} }
|
||||
state[bufnr] = {
|
||||
gitdir = gitdir,
|
||||
worktree = worktree,
|
||||
lines = {},
|
||||
sidebar_win = win,
|
||||
}
|
||||
|
||||
local function k(lhs, rhs, desc)
|
||||
vim.keymap.set(
|
||||
|
||||
Reference in New Issue
Block a user