Skip to content

Commit d547966

Browse files
committed
feat(input_window): keep input visible in new sessions with auto_hide enabled
1 parent cb09a6f commit d547966

2 files changed

Lines changed: 126 additions & 0 deletions

File tree

lua/opencode/ui/input_window.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,10 +491,14 @@ function M.setup_autocmds(windows, group)
491491
-- Auto-hide input window when auto_hide is enabled and focus leaves
492492
-- Don't hide if displaying a route (slash command output like /help)
493493
-- Don't hide if input contains content
494+
-- Don't hide if output window is empty (new session - user needs to start chat)
495+
local output_window = require('opencode.ui.output_window')
496+
local output_is_empty = output_window.get_buf_line_count() <= 1
494497
if
495498
config.ui.input.auto_hide
496499
and not M.is_hidden()
497500
and not state.display_route
501+
and not output_is_empty
498502
and #state.input_content == 1
499503
and state.input_content[1] == ''
500504
then

tests/unit/input_window_spec.lua

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,128 @@ describe('input_window', function()
358358
end)
359359
end)
360360

361+
describe('auto-hide behavior', function()
362+
local input_buf, output_buf, input_win, output_win
363+
local original_config
364+
365+
before_each(function()
366+
local config = require('opencode.config')
367+
original_config = vim.deepcopy(config.ui)
368+
369+
input_buf = vim.api.nvim_create_buf(false, true)
370+
output_buf = vim.api.nvim_create_buf(false, true)
371+
input_win = vim.api.nvim_open_win(input_buf, true, {
372+
relative = 'editor',
373+
width = 80,
374+
height = 10,
375+
row = 0,
376+
col = 0,
377+
})
378+
output_win = vim.api.nvim_open_win(output_buf, false, {
379+
relative = 'editor',
380+
width = 80,
381+
height = 10,
382+
row = 11,
383+
col = 0,
384+
})
385+
386+
state.windows = {
387+
input_buf = input_buf,
388+
input_win = input_win,
389+
output_buf = output_buf,
390+
output_win = output_win,
391+
}
392+
state.input_content = { '' }
393+
state.display_route = false
394+
395+
config.ui.input.auto_hide = true
396+
end)
397+
398+
after_each(function()
399+
local config = require('opencode.config')
400+
config.ui = original_config
401+
402+
pcall(vim.api.nvim_win_close, input_win, true)
403+
pcall(vim.api.nvim_win_close, output_win, true)
404+
pcall(vim.api.nvim_buf_delete, input_buf, { force = true })
405+
pcall(vim.api.nvim_buf_delete, output_buf, { force = true })
406+
state.windows = nil
407+
state.input_content = nil
408+
state.display_route = nil
409+
input_window._hidden = false
410+
end)
411+
412+
it('should NOT auto-hide when output window is empty (new session)', function()
413+
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, { '' })
414+
415+
local group = vim.api.nvim_create_augroup('test_input_window_autohide', { clear = true })
416+
input_window.setup_autocmds(state.windows, group)
417+
418+
vim.api.nvim_exec_autocmds('WinLeave', {
419+
buffer = input_buf,
420+
modeline = false,
421+
})
422+
423+
assert.is_false(input_window.is_hidden())
424+
assert.is_true(vim.api.nvim_win_is_valid(input_win))
425+
426+
vim.api.nvim_del_augroup_by_id(group)
427+
end)
428+
429+
it('should auto-hide when output window has content and input is empty', function()
430+
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, { 'User message', 'Assistant response' })
431+
432+
local group = vim.api.nvim_create_augroup('test_input_window_autohide', { clear = true })
433+
input_window.setup_autocmds(state.windows, group)
434+
435+
vim.api.nvim_exec_autocmds('WinLeave', {
436+
buffer = input_buf,
437+
modeline = false,
438+
})
439+
440+
assert.is_true(input_window.is_hidden())
441+
442+
vim.api.nvim_del_augroup_by_id(group)
443+
end)
444+
445+
it('should NOT auto-hide when input has content', function()
446+
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, { 'User message', 'Assistant response' })
447+
vim.api.nvim_buf_set_lines(input_buf, 0, -1, false, { 'user typing...' })
448+
state.input_content = { 'user typing...' }
449+
450+
local group = vim.api.nvim_create_augroup('test_input_window_autohide', { clear = true })
451+
input_window.setup_autocmds(state.windows, group)
452+
453+
vim.api.nvim_exec_autocmds('WinLeave', {
454+
buffer = input_buf,
455+
modeline = false,
456+
})
457+
458+
assert.is_false(input_window.is_hidden())
459+
assert.is_true(vim.api.nvim_win_is_valid(input_win))
460+
461+
vim.api.nvim_del_augroup_by_id(group)
462+
end)
463+
464+
it('should NOT auto-hide when display_route is active', function()
465+
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, { 'User message', 'Assistant response' })
466+
state.display_route = true
467+
468+
local group = vim.api.nvim_create_augroup('test_input_window_autohide', { clear = true })
469+
input_window.setup_autocmds(state.windows, group)
470+
471+
vim.api.nvim_exec_autocmds('WinLeave', {
472+
buffer = input_buf,
473+
modeline = false,
474+
})
475+
476+
assert.is_false(input_window.is_hidden())
477+
assert.is_true(vim.api.nvim_win_is_valid(input_win))
478+
479+
vim.api.nvim_del_augroup_by_id(group)
480+
end)
481+
end)
482+
361483
describe('auto-show when hidden', function()
362484
local input_buf, output_buf, input_win, output_win
363485

0 commit comments

Comments
 (0)