From c9b02989da04d31f4ff2f8b34fa5fa2e9b792f78 Mon Sep 17 00:00:00 2001 From: Oscar Wallberg Date: Mon, 27 Apr 2026 13:59:20 +0200 Subject: [PATCH] perf(git): stash sidebar window in state --- lua/git/status_win.lua | 49 +++++++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/lua/git/status_win.lua b/lua/git/status_win.lua index 29dacdc..337229d 100644 --- a/lua/git/status_win.lua +++ b/lua/git/status_win.lua @@ -32,6 +32,7 @@ local SIDEBAR_WIDTH = 50 ---@field gitdir string ---@field worktree string ---@field lines table +---@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(