Skip to content

Commit 823e32c

Browse files
authored
fix(input_window): disable dynamic height if min_height == max_height (#260)
* fix(input_window): disable dynamic height if min_height == max_height * test: add unit test to check that dynamic resize can be disabled * refactor: fix type warning * test: add unit test for dynamic height enabled
1 parent 34f9f42 commit 823e32c

File tree

2 files changed

+84
-3
lines changed

2 files changed

+84
-3
lines changed

lua/opencode/ui/input_window.lua

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,14 @@ local function get_winbar_height(windows)
3838
return 0
3939
end
4040

41+
local dynamic_height_enabled = config.ui.input.min_height ~= config.ui.input.max_height
42+
43+
---@return integer
4144
local function calculate_height(windows)
4245
local total_height = vim.api.nvim_get_option_value('lines', {})
46+
if not dynamic_height_enabled then
47+
return math.floor(total_height * config.ui.input.min_height)
48+
end
4349
local min_height = math.max(1, math.floor(total_height * config.ui.input.min_height))
4450
local max_height = math.max(min_height, math.floor(total_height * config.ui.input.max_height))
4551
local content_height = get_content_height(windows) + get_winbar_height(windows)
@@ -274,7 +280,6 @@ function M.setup(windows)
274280
if config.ui.position ~= 'current' then
275281
set_win_option('winfixbuf', true, windows)
276282
end
277-
set_win_option('winfixheight', true, windows)
278283
set_win_option('winfixwidth', true, windows)
279284

280285
M.update_dimensions(windows)
@@ -295,18 +300,21 @@ function M.update_dimensions(windows)
295300
end
296301

297302
function M.schedule_resize(windows)
303+
if not dynamic_height_enabled then
304+
return
305+
end
298306
windows = windows or state.windows
299307
if not M.mounted(windows) or M._resize_scheduled then
300308
return
301309
end
302310

303311
M._resize_scheduled = true
304-
vim.schedule(function()
312+
vim.defer_fn(function()
305313
M._resize_scheduled = false
306314
if M.mounted(windows) then
307315
M.update_dimensions(windows)
308316
end
309-
end)
317+
end, math.floor(1000 / 60)) -- throttle to 60 FPS
310318
end
311319

312320
function M.refresh_placeholder(windows, input_lines)

tests/unit/zoom_spec.lua

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,79 @@ describe('ui zoom state', function()
126126

127127
assert.equals(80, state.pre_zoom_width)
128128
end)
129+
130+
it('calls update_dimensions when dynamic height is enabled', function()
131+
config.setup({
132+
ui = {
133+
input = {
134+
min_height = 0.1,
135+
max_height = 0.25,
136+
},
137+
},
138+
})
139+
140+
package.loaded['opencode.ui.input_window'] = nil
141+
local dynamic_height_input_window = require('opencode.ui.input_window')
142+
143+
local update_calls = 0
144+
local original_defer_fn = vim.defer_fn
145+
local original_update_dimensions = dynamic_height_input_window.update_dimensions
146+
147+
vim.defer_fn = function(fn)
148+
fn()
149+
end
150+
151+
dynamic_height_input_window.update_dimensions = function(...)
152+
update_calls = update_calls + 1
153+
return original_update_dimensions(...)
154+
end
155+
156+
dynamic_height_input_window.schedule_resize(windows)
157+
158+
assert.equals(1, update_calls)
159+
160+
vim.defer_fn = original_defer_fn
161+
dynamic_height_input_window.update_dimensions = original_update_dimensions
162+
package.loaded['opencode.ui.input_window'] = nil
163+
require('opencode.ui.input_window')
164+
end)
165+
166+
it('does not call update_dimensions when dynamic height disabled (fixed input height)', function()
167+
config.setup({
168+
ui = {
169+
input = {
170+
min_height = 0.2,
171+
max_height = 0.2,
172+
},
173+
},
174+
})
175+
176+
package.loaded['opencode.ui.input_window'] = nil
177+
local fixed_height_input_window = require('opencode.ui.input_window')
178+
179+
local update_calls = 0
180+
local original_update_dimensions = fixed_height_input_window.update_dimensions
181+
fixed_height_input_window.update_dimensions = function(...)
182+
update_calls = update_calls + 1
183+
return original_update_dimensions(...)
184+
end
185+
186+
fixed_height_input_window.schedule_resize(windows)
187+
188+
assert.equals(0, update_calls)
189+
190+
fixed_height_input_window.update_dimensions = original_update_dimensions
191+
config.setup({
192+
ui = {
193+
input = {
194+
min_height = 0.1,
195+
max_height = 0.25,
196+
},
197+
},
198+
})
199+
package.loaded['opencode.ui.input_window'] = nil
200+
require('opencode.ui.input_window')
201+
end)
129202
end)
130203

131204
describe('output_window.update_dimensions', function()

0 commit comments

Comments
 (0)