-
Notifications
You must be signed in to change notification settings - Fork 6k
feat: add layout system for TUI #5020
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Replace hard-coded layout values with config system that allows users to customize spacing, padding, and UI element visibility. - Add LayoutProvider context following theme system pattern - Include two built-in layouts: default (preserves original behavior) and dense (optimized for small terminals) - Support custom user layouts via ~/.config/opencode/layout/*.jsonc - Add /layout command and dialog for switching layouts - Add layout field to config - Maintain 100% backward compatibility New layout system enables users to optimize TUI for different terminal sizes and personal preferences without modifying code.
That was finished quite some time ago |
|
(OpenTUI is done) Great. Then this should be an easy integration. |
|
It depends on what you mean by that. If you mean “remove the line itself", then yes. The “minimal” example in the documentation does that. I can send other examples. If you mean “don’t highlight it as part of the message” then no. Not currently. That would have been more of a code change and I was trying to be minimally intrusive. It has to do with where the margin is added. I’m happy to make the change though if there is desire. It annoyed me too :) UPDATE: OK. I see how to do it, and it's pretty clean. Implementing it now. I'll see if I can figure out how to update a PR :). Worst case, I can cancel this one and make a new one. Basically, it's just a matter of giving agent messages and user messages their own top and bottom padding variables, rather than sharing them. UPDATE 2: Done and pushed. "dense" should be better now. |
Replace generic messagePaddingTop/Bottom with separate controls for user and assistant messages. This enables visual separation by moving blank lines from highlighted user message area to unhighlighted assistant area. Changes: - Split messagePaddingTop/Bottom into user/assistant variants in LayoutConfig - Update default layout: move blank line from user bottom to assistant top - Update dense layout: minimal padding with visual separation preserved - Apply padding to TextPart component (was missing before) Result: Same total spacing but improved visual clarity - blank line between user→assistant messages no longer extends user message background color.
|
thanks for uploading the screenshots... I'm facepalming for not doing it myself! |
…hanks for patience)
|
I just pushed a formatting update to better comply with CONTRIBUTING.md. Sorry about that. This is actually my first github PR and I'm kinda learning in real time. |
fyi you can use a spoiler tag in the description to hide the lengthy AI generated overview |
|
I added the spoiler tag, and I pushed a new commit to resolve a minor conflict. I wanted to thank you, @avarayr , for the warm welcome and friendly help. Much appreciated! These environments can sometimes smack people for doing things a little bit wrong, and it's so much better to gently nudge them toward doing things right :) |
|
@rekram1-node Would love to see this merged! Apologies for ping but this is a blocker preventing me from using opencode. I'm visually impaired and having huge all-around paddings is very inefficient for me, screen-space wise. |
|
This is also fairly needed for me, connecting to TUI from an Android phone. I've resolved it eventually from source, with quite a bit of struggle( bun version .33 was forced WTF) by Amazing result, I can confirm! |



Extensible Layout System (Human-Written Description)
This PR addresses:
What This Does
This PR adds an spatial
layoutconfiguration to the OpenCode TUI. It is a complement to the color configuration provided bythemes, and and is modeled after thethemessystem. This feature allows users to customize spacing, padding, and UI element visibility through JSON/JSONC configuration files.Users can now:
/layoutcommand~/.config/opencode/layout/Why This Matters
I am visually impaired, and I live in the terminal. I love OpenCode, but the original hardcoded layout simply didn't scale well to large fonts and the resulting small terminals, like 80x24. All of the margins around messages, input boxes, and status information consumed excessive space, leaving little room for actual content.
This extensible layout system solves these problems while:
user-custom layouts
LLM-generated details: read 'em if they're helpful
Code Quality & Diff Size
Statistics
Files Changed
New Files Added
packages/opencode/src/cli/cmd/tui/context/layout.tsx(186 lines)packages/opencode/src/cli/cmd/tui/component/dialog-layout-list.tsx(61 lines)packages/opencode/src/cli/cmd/tui/context/layout/default.jsonc(45 lines)packages/opencode/src/cli/cmd/tui/context/layout/dense.jsonc(45 lines)Total new code: ~337 lines (includes 2 well-commented JSONC config files)
Review-Friendliness
The diff is highly reviewable:
Minimal Intrusiveness
Design Philosophy
Core principle: Replace hard-coded layout values with configurable ones, without changing architecture.
What I Changed
Modified Existing Code
session/index.tsx - Replaced hard-coded spacing values:
messageSeparation: 1→ctx.layout().messageSeparationtoolMarginTop: 1→ctx.layout().toolMarginTopagentInfoMarginTop: 1→ctx.layout().agentInfoMarginTopbackgroundPanel→backgroundElement(consistency with input box)prompt/index.tsx - Made input box configurable:
inputBoxPaddingTop,inputBoxPaddingBottomapp.tsx - Added layout system integration:
autocomplete.tsx - Added
/layoutslash command (5 lines)config.ts - Changed layout field from enum to string (4 lines)
What I DIDN'T Change
Backward Compatibility
Convention Compliance
Code Style
Followed OpenCode's conventions from CONTRIBUTING.md:
const, avoidedletany.catch()patterns where applicableArchitecture Patterns
Followed existing OpenCode patterns throughout:
1. Context Provider Pattern
ThemeProvider,LocalProvider, etc.2. Config File Pattern
~/.config/opencode/layout/~/.config/opencode/themes/)layout/*.{json,jsonc}command/,agent/,mode/,plugin/,tool/)3. Built-in Defaults
jsonc-parser4. Dialog Pattern
DialogThemeList,DialogModelList, etc.5. Command Registration
Naming Conventions
layout/(singular, follows codebase convention)useLayout()(matchesuseTheme(),useLocal())LayoutProvider(matchesThemeProvider)DialogLayoutList(matchesDialogThemeList)LayoutConfig(matchesThemeColors)File Organization
Documentation
Inline Documentation
JSONC Files - Comprehensive comments explaining every field:
{ "config": { // Vertical spacing between consecutive messages "messageSeparation": 1, // Padding inside individual message containers "messagePaddingTop": 1, "messagePaddingBottom": 1, "messagePaddingLeft": 2, // Padding around the entire session container "containerPaddingTop": 1, "containerPaddingBottom": 1, // ... etc } }Users can reference built-in layouts as examples when creating custom layouts.
TypeScript - Clear type definitions:
18 configurable fields, all clearly named and typed.
Code Comments
Validation & Forward Compatibility
Design Goals
The validation system is designed to be tolerant of version mismatches:
Implementation
Version Compatibility Scenarios
Scenario 1: Old Layout, New Version
showSomethingshowSomethinguses default valueScenario 2: New Layout, Old Version
Scenario 3: Corrupted/Malformed Config
Error Handling
This approach ensures:
Testing Considerations
Manual Testing Completed
~/.config/opencode/layout//layoutcommandEdge Cases Tested
Potential Questions from Reviewers
Q: "Why not use the existing theme system for this?"
A: Layouts control spacing/structure, themes control colors. Separating concerns allows users to mix any layout with any theme (e.g., "bumble theme with dense layout").
Q: "Why JSONC instead of plain JSON?"
A: Comments are invaluable for user education and documentation. The built-in layout files serve as examples, and inline comments explain what each field does. This follows the precedent set by the theme system and other config systems in the codebase. Plain JSON is also supported for users who prefer it.
Q: "Performance impact of loading layouts?"
A: Minimal - layouts load once at startup and when the
/layoutdialog opens (user-triggered). There is no per-frame overhead.Q: "Is this adding too many config options?"
A: All fields have sensible defaults. Users only configure what they want different from defaults. Most users will use built-in layouts (default, dense). Power users who customize will appreciate the granularity. The commented JSONC files make it easy to understand what each option does.
Q: "What about discoverability?"
A: Users discover layouts through:
/layoutcommand (autocomplete suggests it)Risk Assessment
Low Risk ✓
Handled Edge Cases
All anticipated issues have error handling:
Maintenance Burden
loaded from a JSONC file
Summary
This implementation: