Skip to content

Conversation

@aweis89
Copy link
Contributor

@aweis89 aweis89 commented Dec 27, 2025

Summary

  • Add ability to toggle (hide/show) the input window independently of the output window
  • Add new ui.input.dynamic config option that automatically hides the input window when focus moves to the output window or when a prompt is submitted

Motivation

When working with AI responses, the output window benefits from maximum screen real estate. The input window (especially when configured larger) takes up space that isn't needed while waiting for or reading responses. This feature allows the input window to stay out of the way until you're ready to type the next prompt.

Features

Toggle Input Window

  • New toggle_input API function and command (:Opencode toggle_input)
  • Default keymap: <M-i> (Alt+i) in both input and output windows
  • When hidden, the input window is completely closed (not just minimized) to give full space to the output
  • Input buffer content is preserved when hidden

Dynamic Input Mode (ui.input.auto_hide = true)

  • When enabled, the input window automatically hides when:
    • Submitting a prompt (<cr>)
    • Focus moves to the output window (via any method - keymaps, mouse, <C-w> commands, etc.)
  • The input window automatically shows when focusing it via focus_input, open_input, or toggle_pane
  • When toggling the UI with dynamic mode enabled, no longer defaults to last focused window (always focuses input)

Bug Fixes

Auto-scroll preservation during dynamic input resize

When the input window hides/shows with dynamic = true, the output window resizes. This could incorrectly update viewport_at_bottom via the WinScrolled autocmd, breaking auto-scroll. Fixed by:

  • Capturing was_at_bottom state before hide/show
  • Scheduling scroll_to_bottom() after resize if previously at bottom

Tab keymap conflicts with completion plugins

  • Fix: Restricted the default <Tab> toggle focus mapping to only trigger in normal mode, preventing conflicts with auto-complete mappings that use <Tab> in insert mode

Test Fixes

Date formatting tests fail on year boundaries (CI)

Tests for util.format_time failed when run on year boundaries (e.g., Jan 1, 2026):

  • "formats yesterday" expected 31 Dec 09:46 PM but got 31 Dec 2025 09:46 PM (year included because Dec 31 is a different year than Jan 1)
  • "formats last week" had the same issue
  • "handles large millisecond timestamps" also failed due to year comparison

Fix: Made tests year-boundary-aware by checking if test dates fall in the same year as today before asserting the expected format pattern.

Files Changed

  • lua/opencode/api.lua - Add toggle_input, update submit_input_prompt, toggle
  • lua/opencode/config.lua - Add ui.input.dynamic option and keymaps
  • lua/opencode/ui/autocmds.lua - Prevent closing all windows during toggle
  • lua/opencode/ui/input_window.lua - Add toggle, _hide, _show, is_hidden functions; preserve scroll position
  • lua/opencode/ui/output_window.lua - Auto-hide input on focus when dynamic enabled
  • lua/opencode/ui/ui.lua - Handle hidden state in focus_input, simplify toggle_pane
  • tests/unit/util_spec.lua - Fix year-boundary-aware date formatting tests

@aweis89 aweis89 marked this pull request as draft December 27, 2025 06:53
@aweis89 aweis89 marked this pull request as ready for review December 27, 2025 17:45
@aweis89
Copy link
Contributor Author

aweis89 commented Jan 1, 2026

@sudo-tee curious to hear if you had any thoughts on this if you had a chance to try it out.

  • Perhaps dynamic = true should not be the default?
  • It is more inline with the way the TUI works, where the input window is hiddent during model output I believe
  • The main advantage for me is having a larger input window without having to compromise on output window size
  • Hitting i from the output window, to get the input window (in insert mode) has been perferable to a static input window in my experience but curious if you have reservations

@sudo-tee
Copy link
Owner

sudo-tee commented Jan 1, 2026

I didn't had time to look at it yet. Been busy with the holidays and family. But I will look at it pretty soon

Copy link
Owner

@sudo-tee sudo-tee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea.

However the implementation feels a bit rough. There is a good amount of layout shifting when toggling the input.

When I move the cursor to the code window the input should also auto_hide, as it feels weird that it hide when focusing back to the opencode window. I attached a video

Screen.Recording.2026-01-05.074018.mp4

I think a better solution would be to make the input a floating window when in auto_hide mode, it would reduce the layout shifting.

What do you think ?

sudo-tee added a commit that referenced this pull request Jan 5, 2026
The permission request seems to have changed it's format

I updated the permission handling to support both format

This should fix #156
@sudo-tee sudo-tee closed this in 5404cd1 Jan 5, 2026
@sudo-tee sudo-tee reopened this Jan 5, 2026
@aaronweisberg
Copy link

aaronweisberg commented Jan 5, 2026

I like the idea.

However the implementation feels a bit rough. There is a good amount of layout shifting when toggling the input.

When I move the cursor to the code window the input should also auto_hide, as it feels weird that it hide when focusing back to the opencode window. I attached a video
Screen.Recording.2026-01-05.074018.mp4

I mostly used this in full-screen mode position = "current" so I didn't consider the intended behavior when switching to another split. I think the input window should be hidden whenever the focus shifts away from the input window instead. I think this will feel less weird. Curious to hear what you think if you're able to try again though.

I think a better solution would be to make the input a floating window when in auto_hide mode, it would reduce the layout shifting.

What do you think ?

I think a floating window would add some additional complexities. Ideally when the input window is being hidden, we want to the output window to maximize it's size (so static padding wouldn't be ideal), we also don't want to hide the latest text of the output window behind the input window when the input window is open. Perhaps this can be explored in a future dedicated PR if there's a way to make this better through a float though I'm a bit skeptical.

@aweis89 aweis89 requested a review from sudo-tee January 6, 2026 00:00
- introduce toggle_input function to manage input window visibility
- add keybindings for toggling input window
- implement auto-hide behavior for input window after message submission
- adjust focus handling to include hidden input window

Closes sudo-tee#123
@aweis89 aweis89 force-pushed the dynamic-input-window branch from 19b6ce1 to 69d6d6d Compare January 6, 2026 00:24
@sudo-tee
Copy link
Owner

sudo-tee commented Jan 6, 2026

I think a floating window would add some additional complexities. Ideally when the input window is being hidden, we want to the output window to maximize it's size (so static padding wouldn't be ideal), we also don't want to hide the latest text of the output window behind the input window when the input window is open. Perhaps this can be explored in a future dedicated PR if there's a way to make this better through a float though I'm a bit skeptical.

This is reasonable as long as it's not the default

Copy link
Owner

@sudo-tee sudo-tee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks fine now as it is not the default behavior.

The only thing needed is to remove unnecessary comments. Most of the time it's pretty obvious on what the code does. I commented on a couple of ones as example.

- adjust scroll_to_bottom function to include a force parameter
- ensure auto-scrolling respects user scroll position unless forced
@aweis89
Copy link
Contributor Author

aweis89 commented Jan 7, 2026

Fixed some auto-scrolling so the dynamic input window doesn't block the latest text.
I think this should be good to go 🎉

@sudo-tee
Copy link
Owner

sudo-tee commented Jan 8, 2026

Thanks for the fixes.

It should be good to go

@sudo-tee sudo-tee merged commit 009c07d into sudo-tee:main Jan 8, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants