Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lua/opencode/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
---@field api_client OpencodeApiClient
---@field event_manager EventManager|nil
---@field pre_zoom_width integer|nil
---@field last_window_width_ratio number|nil
---@field required_version string
---@field opencode_cli_version string|nil
---@field current_cwd string|nil
Expand Down
6 changes: 1 addition & 5 deletions lua/opencode/ui/input_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,7 @@ local function apply_dimensions(windows, height)
return
end

local total_width = vim.api.nvim_get_option_value('columns', {})
local width_ratio = state.pre_zoom_width and config.ui.zoom_width or config.ui.window_width
local width = math.floor(total_width * width_ratio)

pcall(vim.api.nvim_win_set_config, windows.input_win, { width = width, height = height })
pcall(vim.api.nvim_win_set_config, windows.input_win, { height = height })
end

function M.create_buf()
Expand Down
12 changes: 11 additions & 1 deletion lua/opencode/ui/output_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,17 @@ function M.update_dimensions(windows)
return
end
local total_width = vim.api.nvim_get_option_value('columns', {})
local width_ratio = state.pre_zoom_width and config.ui.zoom_width or config.ui.window_width

local width_ratio
if windows.saved_width_ratio then
width_ratio = windows.saved_width_ratio
windows.saved_width_ratio = nil
elseif state.pre_zoom_width then
width_ratio = config.ui.zoom_width
else
width_ratio = config.ui.window_width
end

local width = math.floor(total_width * width_ratio)

vim.api.nvim_win_set_config(windows.output_win, { width = width })
Expand Down
10 changes: 10 additions & 0 deletions lua/opencode/ui/ui.lua
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,14 @@ function M.hide_visible_windows(windows)
end

local snapshot = capture_hidden_snapshot(windows)

-- Only save width ratio for split modes (not dialog/current mode)
if config.ui.position ~= 'current' then
local total_cols = vim.o.columns
local current_width = vim.api.nvim_win_get_width(windows.output_win)
state.last_window_width_ratio = current_width / total_cols
end

state.clear_hidden_window_state()

prepare_window_close()
Expand Down Expand Up @@ -227,6 +235,7 @@ function M.restore_hidden_windows()
windows.output_win = win_ids.output_win
windows.footer_win = nil
windows.output_was_at_bottom = hidden.output_was_at_bottom == true
windows.saved_width_ratio = state.last_window_width_ratio

state.set_cursor_position('input', hidden.input_cursor)
state.set_cursor_position('output', hidden.output_cursor)
Expand Down Expand Up @@ -349,6 +358,7 @@ function M.create_windows()

windows.input_win = win_ids.input_win
windows.output_win = win_ids.output_win
windows.saved_width_ratio = state.last_window_width_ratio

input_window.setup(windows)
output_window.setup(windows)
Expand Down
62 changes: 54 additions & 8 deletions tests/unit/zoom_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -99,24 +99,23 @@ describe('ui zoom state', function()
end)

describe('input_window.update_dimensions', function()
it('uses default window_width when not zoomed', function()
it('does not change input window width', function()
local original_width = vim.api.nvim_win_get_width(windows.input_win)

input_window.update_dimensions(windows)

local expected_width = math.floor(config.ui.window_width * vim.o.columns)
local actual_width = vim.api.nvim_win_get_width(windows.input_win)

assert.equals(expected_width, actual_width)
assert.equals(original_width, actual_width)
end)

it('uses zoom_width when zoomed', function()
it('does not change input window width when zoomed', function()
state.pre_zoom_width = 80
local original_width = vim.api.nvim_win_get_width(windows.input_win)

input_window.update_dimensions(windows)

local expected_width = math.floor(config.ui.zoom_width * vim.o.columns)
local actual_width = vim.api.nvim_win_get_width(windows.input_win)

assert.equals(expected_width, actual_width)
assert.equals(original_width, actual_width)
end)

it('preserves zoom state after update_dimensions', function()
Expand Down Expand Up @@ -267,4 +266,51 @@ describe('ui zoom state', function()
assert.is_nil(state.pre_zoom_width)
end)
end)

describe('window width persistence', function()
it('saves width ratio when hiding windows', function()
local custom_width = 100
vim.api.nvim_win_set_width(windows.output_win, custom_width)
ui.hide_visible_windows(windows)

local expected_ratio = custom_width / vim.o.columns
assert.is_not_nil(state.last_window_width_ratio)
assert.near(expected_ratio, state.last_window_width_ratio, 0.001)
end)

it('does not save width in dialog mode (position=current)', function()
local original_position = config.ui.position
config.ui.position = 'current'
state.last_window_width_ratio = nil

ui.hide_visible_windows(windows)
assert.is_nil(state.last_window_width_ratio)

config.ui.position = original_position
end)

it('uses saved width ratio in output_window.update_dimensions', function()
local saved_ratio = 0.6
windows.saved_width_ratio = saved_ratio

output_window.update_dimensions(windows)

local expected_width = math.floor(saved_ratio * vim.o.columns)
local actual_width = vim.api.nvim_win_get_width(windows.output_win)
assert.equals(expected_width, actual_width)
assert.is_nil(windows.saved_width_ratio)
end)

it('prefers saved width over zoom width', function()
state.pre_zoom_width = 80
local saved_ratio = 0.5
windows.saved_width_ratio = saved_ratio

output_window.update_dimensions(windows)

local expected_width = math.floor(saved_ratio * vim.o.columns)
local actual_width = vim.api.nvim_win_get_width(windows.output_win)
assert.equals(expected_width, actual_width)
end)
end)
end)
Loading