Repository navigation
feat(tui): allow session names to wrap to two lines in dialog (#6165) - #6166
CasualDeveloper wants to merge 1 commit into
Conversation
5df4953 to
d99001d
Compare
d99001d to
f604825
Compare
fc54502 to
7b2b7de
Compare
|
Will continue rebasing on top of release tags as they're set. |
7b2b7de to
49c726a
Compare
49c726a to
3dbf5e3
Compare
There was a problem hiding this comment.
Pull request overview
This PR enhances the TUI dialog to allow long session names to wrap to two lines instead of being truncated, improving readability for users with lengthy session names.
Key changes:
- Enabled text wrapping in dialog select options with
flexWrap="wrap"andwrapMode="word" - Removed redundant
paddingLeft={3}that was causing incorrect wrap calculations - Removed unused
takeimport from remeda
Reviewed changes
Copilot reviewed 1 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| packages/sdk/js/package.json | Added missing newline at end of file (formatting fix) |
| packages/plugin/package.json | Added missing newline at end of file (formatting fix) |
| packages/opencode/src/cli/cmd/tui/ui/dialog-select.tsx | Implemented text wrapping for dialog options by adding flex wrap support, configuring word-wrap mode with 2-line max height, and removing conflicting padding |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| > | ||
| {Locale.truncate(props.title, 61)} | ||
| {Locale.truncate(props.title, 122)} |
There was a problem hiding this comment.
Using Locale.truncate with wrapMode="word" and maxHeight={2} is redundant. When wrapping is enabled, the text element will naturally wrap and constrain to maxHeight, making manual truncation unnecessary.
Additionally, the limit of 122 characters (exactly double the original 61) appears arbitrary and doesn't account for the actual available width, which varies based on terminal size, padding, and other UI elements.
Consider removing Locale.truncate entirely and letting the wrapping behavior handle long text naturally. Other parts of the codebase (e.g., dialog-status.tsx, todo-item.tsx, toast.tsx) use wrapMode="word" without manual truncation.
| {Locale.truncate(props.title, 122)} | |
| {props.title} |
There was a problem hiding this comment.
I checked with Claude and while it's a reasonable idea, it's not accurate for our desired UX.
Claude says it’s not redundant here:
- wrapMode="word" + maxHeight={2} limits layout height, but it does not guarantee a nice truncation indicator.
- Without Locale.truncate, overlong titles will typically just get hard-clipped at line 2 (depending on opentui’s overflow behavior), meaning users lose the “…” hint that there’s more text.
- Your examples (toast.tsx, dialog-status.tsx, todo-item.tsx) often use wrapping because they’re OK with showing as much as needed (or they don’t enforce “2 lines max with ellipsis”), so it's a different requirement.
What is true in your comment though:
- 122 is heuristic/arbitrary and not width-aware.
But given opentui doesn’t give us an easy “truncate to N lines with ellipsis based on actual rendered width” primitive, the heuristic truncation is doing a job: “2 lines max, and show an ellipsis”. Claude suggests that if we wanted to improve this “properly”, we’d need a width-aware truncation (measure available width at runtime and truncate accordingly) or a library feature that truncates to N wrapped lines with ellipsis. That’s likely an opentui-level enhancement.
a833c2c to
968d709
Compare
968d709 to
452fc3e
Compare
5243f6a to
6c10ee6
Compare
bd214cc to
a7d1cc1
Compare
00637c0 to
71e0ba2
Compare
f1ae801 to
08fa7f7
Compare
0037f64 to
dec6323
Compare
8ece7ac to
fa6786c
Compare
a1ac33a to
2c6e50c
Compare
|
Fork updated to sync with dev (as of 5b60e51). |
Allow the Sessions dialog to use its reserved second line for long titles while keeping other dialogs single-line by default. Account for footer and gutter width, preserve repeated spaces, normalize hard whitespace, and use display-width-aware wrapping with focused tests for truncation and Unicode cases.
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Closes #22480
Relates to #6165
Type of change
What does this PR do?
Allows long titles in the TUI Sessions dialog to wrap to a second line, while keeping other
DialogSelectusers single-line by default.The implementation adds an opt-in
maxLinesprop, uses display-width-aware wrapping/truncation for Unicode/CJK text, reserves footer width for workspace status metadata, and keeps the current lazy gutter rendering behavior.How did you verify your code works?
bun test --timeout 20000 test/cli/tui/dialog-select.test.tsbun turbo typecheckFocused tests cover two-line wrapping, truncation, reserved footer width, whitespace preservation, and CJK/wide-token display width.
Screenshots / recordings
Before:

After:

Checklist