perf(git): stash sidebar window in state
This commit is contained in:
+29
-10
@@ -32,6 +32,7 @@ local SIDEBAR_WIDTH = 50
|
|||||||
---@field gitdir string
|
---@field gitdir string
|
||||||
---@field worktree string
|
---@field worktree string
|
||||||
---@field lines table<integer, ow.Git.StatusEntry>
|
---@field lines table<integer, ow.Git.StatusEntry>
|
||||||
|
---@field sidebar_win integer?
|
||||||
---@field diff_left_win integer?
|
---@field diff_left_win integer?
|
||||||
---@field diff_right_win integer?
|
---@field diff_right_win integer?
|
||||||
---@field user_aucmd integer?
|
---@field user_aucmd integer?
|
||||||
@@ -44,6 +45,8 @@ local group =
|
|||||||
vim.api.nvim_create_augroup("ow.git.status_win", { clear = false })
|
vim.api.nvim_create_augroup("ow.git.status_win", { clear = false })
|
||||||
local ns = vim.api.nvim_create_namespace("ow.git.status_win")
|
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? win
|
||||||
---@return integer? bufnr
|
---@return integer? bufnr
|
||||||
local function find_sidebar()
|
local function find_sidebar()
|
||||||
@@ -55,6 +58,20 @@ local function find_sidebar()
|
|||||||
end
|
end
|
||||||
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
|
---@param entry ow.Git.StatusEntry
|
||||||
---@return string?
|
---@return string?
|
||||||
local function entry_code(entry)
|
local function entry_code(entry)
|
||||||
@@ -325,16 +342,14 @@ local function refresh(bufnr)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local saved_path, saved_sha
|
local saved_path, saved_sha
|
||||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
local sidebar_win = sidebar_win_for(s)
|
||||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
if sidebar_win then
|
||||||
local lnum = vim.api.nvim_win_get_cursor(win)[1]
|
local lnum = vim.api.nvim_win_get_cursor(sidebar_win)[1]
|
||||||
local entry = s.lines[lnum]
|
local entry = s.lines[lnum]
|
||||||
if entry then
|
if entry then
|
||||||
saved_path = entry.path
|
saved_path = entry.path
|
||||||
saved_sha = entry.sha
|
saved_sha = entry.sha
|
||||||
end
|
end
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
fetch_status(s.worktree, function(branch, groups)
|
fetch_status(s.worktree, function(branch, groups)
|
||||||
@@ -350,11 +365,10 @@ local function refresh(bufnr)
|
|||||||
(saved_path and entry.path == saved_path)
|
(saved_path and entry.path == saved_path)
|
||||||
or (saved_sha and entry.sha == saved_sha)
|
or (saved_sha and entry.sha == saved_sha)
|
||||||
then
|
then
|
||||||
for _, win in ipairs(vim.api.nvim_list_wins()) do
|
local win = sidebar_win_for(s)
|
||||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
if win then
|
||||||
pcall(vim.api.nvim_win_set_cursor, win, { lnum, 0 })
|
pcall(vim.api.nvim_win_set_cursor, win, { lnum, 0 })
|
||||||
end
|
end
|
||||||
end
|
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -554,7 +568,7 @@ local function show_diff(s, entry, focus_left)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
---@cast entry ow.Git.FileEntry
|
---@cast entry ow.Git.FileEntry
|
||||||
local sidebar_win = find_sidebar()
|
local sidebar_win = sidebar_win_for(s)
|
||||||
if not sidebar_win then
|
if not sidebar_win then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@@ -788,7 +802,12 @@ local function open(worktree)
|
|||||||
vim.wo[win].winfixwidth = true
|
vim.wo[win].winfixwidth = true
|
||||||
vim.api.nvim_win_set_width(win, SIDEBAR_WIDTH)
|
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)
|
local function k(lhs, rhs, desc)
|
||||||
vim.keymap.set(
|
vim.keymap.set(
|
||||||
|
|||||||
Reference in New Issue
Block a user