Skip to content

Commit 21ae533

Browse files
jensenojsoujinsai
andauthored
handle split resize safely + use store subscribe (#328)
* fix(ui): handle split resize safely Use window-type-aware resize logic in output_window.update_dimensions. - guard missing or invalid output_win before resizing - use nvim_win_set_width for split windows (relative == '') - keep nvim_win_set_config for floating windows - add regression tests for float-focus resize and invalid window This prevents "Cannot split a floating window" on VimResized while preserving existing zoom width behavior. Verified with: - ./run_tests.sh -t tests/unit/zoom_spec.lua * fix(reference-picker): use store subscribe Follow the state observable API migration by switching reference picker setup from state.subscribe(...) to state.store.subscribe(...). This matches the refactor that centralized observable helpers under state.store and fixes startup error: attempt to call field 'subscribe' (a nil value). Verified with: ./run_tests.sh -t tests/unit/reference_picker_spec.lua --------- Co-authored-by: oujinsai <[email protected]>
1 parent 4d430a1 commit 21ae533

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

lua/opencode/ui/output_window.lua

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ function M.update_dimensions(windows)
132132
if config.ui.position == 'current' then
133133
return
134134
end
135+
136+
if not windows or not windows.output_win or not vim.api.nvim_win_is_valid(windows.output_win) then
137+
return
138+
end
139+
135140
local total_width = vim.api.nvim_get_option_value('columns', {})
136141

137142
local width_ratio
@@ -145,8 +150,17 @@ function M.update_dimensions(windows)
145150
end
146151

147152
local width = math.floor(total_width * width_ratio)
153+
local ok, win_config = pcall(vim.api.nvim_win_get_config, windows.output_win)
154+
if not ok then
155+
return
156+
end
157+
158+
if win_config.relative == '' then
159+
pcall(vim.api.nvim_win_set_width, windows.output_win, width)
160+
return
161+
end
148162

149-
vim.api.nvim_win_set_config(windows.output_win, { width = width })
163+
pcall(vim.api.nvim_win_set_config, windows.output_win, { width = width })
150164
end
151165

152166
function M.get_buf_line_count()

tests/unit/zoom_spec.lua

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,68 @@ describe('ui zoom state', function()
228228

229229
assert.equals(80, state.pre_zoom_width)
230230
end)
231+
232+
it('does not error when focused window is floating and output window is split', function()
233+
local split_buf = vim.api.nvim_create_buf(false, true)
234+
local focus_buf = vim.api.nvim_create_buf(false, true)
235+
local split_win
236+
local focus_win
237+
238+
local normal_win
239+
for _, win in ipairs(vim.api.nvim_list_wins()) do
240+
if vim.api.nvim_win_is_valid(win) and vim.api.nvim_win_get_config(win).relative == '' then
241+
normal_win = win
242+
break
243+
end
244+
end
245+
246+
assert.is_not_nil(normal_win)
247+
vim.api.nvim_set_current_win(normal_win)
248+
vim.cmd('vsplit')
249+
split_win = vim.api.nvim_get_current_win()
250+
vim.api.nvim_win_set_buf(split_win, split_buf)
251+
252+
focus_win = vim.api.nvim_open_win(focus_buf, true, {
253+
relative = 'editor',
254+
width = 20,
255+
height = 5,
256+
row = 1,
257+
col = 1,
258+
style = 'minimal',
259+
})
260+
261+
assert.has_no.errors(function()
262+
output_window.update_dimensions({ output_win = split_win, output_buf = split_buf })
263+
end)
264+
265+
local expected_width = math.floor(config.ui.window_width * vim.o.columns)
266+
assert.equals(expected_width, vim.api.nvim_win_get_width(split_win))
267+
268+
pcall(vim.api.nvim_win_close, focus_win, true)
269+
pcall(vim.api.nvim_win_close, split_win, true)
270+
pcall(vim.api.nvim_buf_delete, focus_buf, { force = true })
271+
pcall(vim.api.nvim_buf_delete, split_buf, { force = true })
272+
end)
273+
274+
it('does not error when output window is invalid', function()
275+
local invalid_buf = vim.api.nvim_create_buf(false, true)
276+
local invalid_win = vim.api.nvim_open_win(invalid_buf, false, {
277+
relative = 'editor',
278+
width = 20,
279+
height = 5,
280+
row = 2,
281+
col = 2,
282+
style = 'minimal',
283+
})
284+
285+
vim.api.nvim_win_close(invalid_win, true)
286+
287+
assert.has_no.errors(function()
288+
output_window.update_dimensions({ output_win = invalid_win, output_buf = invalid_buf })
289+
end)
290+
291+
pcall(vim.api.nvim_buf_delete, invalid_buf, { force = true })
292+
end)
231293
end)
232294

233295
describe('zoom state persistence', function()

0 commit comments

Comments
 (0)