diff --git a/lua/opencode/ui/autocmds.lua b/lua/opencode/ui/autocmds.lua index a3301654..6b4d3dd7 100644 --- a/lua/opencode/ui/autocmds.lua +++ b/lua/opencode/ui/autocmds.lua @@ -75,15 +75,18 @@ function M.setup_autocmds(windows) end end +---@param windows OpencodeWindowState? function M.setup_resize_handler(windows) local resize_group = vim.api.nvim_create_augroup('OpencodeResize', { clear = true }) vim.api.nvim_create_autocmd('VimResized', { group = resize_group, callback = function() + require('opencode.ui.ui').reconcile_windows(windows, 'input') + require('opencode.ui.ui').reconcile_windows(windows, 'output') require('opencode.ui.topbar').render() require('opencode.ui.footer').update_window(windows) - require('opencode.ui.input_window').update_dimensions(windows) - require('opencode.ui.output_window').update_dimensions(windows) + input_window.update_dimensions(windows) + output_window.update_dimensions(windows) end, }) diff --git a/lua/opencode/ui/output_window.lua b/lua/opencode/ui/output_window.lua index b0d8bb4d..b9cfd90e 100644 --- a/lua/opencode/ui/output_window.lua +++ b/lua/opencode/ui/output_window.lua @@ -23,6 +23,7 @@ function M._build_output_win_config() } end +---@param windows OpencodeWindowState? function M.mounted(windows) windows = windows or state.windows return windows and windows.output_buf and windows.output_win and vim.api.nvim_win_is_valid(windows.output_win) diff --git a/lua/opencode/ui/ui.lua b/lua/opencode/ui/ui.lua index 6ddc0482..bf3c4251 100644 --- a/lua/opencode/ui/ui.lua +++ b/lua/opencode/ui/ui.lua @@ -296,4 +296,48 @@ function M.toggle_zoom() end end +---Reconcile window state when duplicate windows may have been created +---This can happen when external commands like 'tabdo' manipulate window layouts +---@param windows OpencodeWindowState? +---@param key string +function M.reconcile_windows(windows, key) + local buf_key = key .. '_buf' + if not windows or not windows[buf_key] then + return + end + + local wins = vim.fn.win_findbuf(windows[buf_key]) + if type(wins) ~= 'table' or #wins == 0 then + return + end + + local valid_wins = {} + for _, win in ipairs(wins) do + if vim.api.nvim_win_is_valid(win) then + table.insert(valid_wins, win) + end + end + if #valid_wins == 0 then + return + end + + local current_tab = vim.api.nvim_get_current_tabpage() + local preferred = nil + for _, win in ipairs(valid_wins) do + if vim.api.nvim_win_get_tabpage(win) == current_tab then + preferred = win + break + end + end + preferred = preferred or valid_wins[1] + + windows[key .. '_win'] = preferred + + for _, win in ipairs(valid_wins) do + if win ~= preferred and vim.api.nvim_win_get_tabpage(win) == current_tab then + pcall(vim.api.nvim_win_close, win, false) + end + end +end + return M