Skip to content

fix: grow TUI composer for wrapped input#3278

Merged
SivanCola merged 1 commit into
esengine:main-v2from
lizhengwu:fix/tui-input-growth
Jun 5, 2026
Merged

fix: grow TUI composer for wrapped input#3278
SivanCola merged 1 commit into
esengine:main-v2from
lizhengwu:fix/tui-input-growth

Conversation

@lizhengwu

Copy link
Copy Markdown
Contributor

摘要

修复 chat TUI 输入框在多行输入场景下不会正确动态增高的问题。

本次修复覆盖两个相关现象:

  • 使用 Ctrl+J 手工换行时,输入框虽然插入了新行,但第一行可能被顶出可视区域。
  • 粘贴较长文本后,内容会发生软换行,但输入框仍保持一行高度,上方 transcript 区域也不会相应缩短。

改动内容

  • 将 chat textarea 初始化逻辑集中到 configureChatTextarea
  • 启用 textarea 自带动态高度:
    • 最小高度:1 行
    • 最大可见高度:5 行
    • 内容高度上限与可见高度解耦,避免超过 5 行后无法继续输入换行
  • 移除清空输入后的手动 SetHeight(1)
  • 保留现有换行快捷键绑定:
    • Ctrl+J
    • Alt+Enter
    • Shift+Enter
  • 当动态高度启用时,让 growInputToFit 不再手动覆盖 textarea 高度,避免和组件内部滚动状态冲突。

背景与原因

之前的实现通过手动统计 \n 来调整输入框高度:

strings.Count(input, "\n") + 1

这个方式有两个问题:

  1. 只能识别显式换行,无法识别因为终端宽度不足产生的软换行。
  2. 在 Ctrl+J 首次换行时,textarea
    会先按一行高度调整内部滚动位置,随后外层再手动增高,导致第一行被滚出可视区域。

改为使用 textarea 自带的 DynamicHeight 后,高度计算由组件按 visual lines
完成,可以同时覆盖手工换行和软换行。

回归测试

新增测试覆盖:

  • Ctrl+J 后输入框增高,且第一行不会被隐藏。
  • 手工换行可以超过输入框最大可见高度,输入内容不会被 5 行可见高度限制。
  • 粘贴长文本触发软换行后,输入框会增高,上方 transcript viewport 会相应缩短。

测试计划

  • go test ./internal/cli -run 'TestManualNewlineGrowsComposerWithoutHidingFirstLine|TestManualNewlineCanExc
    eedVisibleComposerRows|TestSoftWrappedInputGrowsComposerAndShrinksTranscript'
  • go test ./internal/cli -run 'TestTranscriptViewportSizing|TestManualNewlineGrowsComposerWithoutHidingFirs
    tLine|TestManualNewlineCanExceedVisibleComposerRows|TestSoftWrappedInputGrowsComposerAndShrinksTranscript|T
    estPasteMsgFoldsBeforeTextareaConsumesNewlines|TestModalPanelsHideComposerBox|TestMCPManagerHidesComposerBo
    x|Test.*Completion|Test.*Paste|Test.*Input|Test.*Viewport|Test.*Render'
  • go test ./internal/cli
  • git diff --check

Use textarea dynamic height so manual newlines and soft-wrapped pasted text expand the composer without hiding earlier lines.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@github-actions github-actions Bot added the v2 Go rewrite (1.x) — main-v2 branch, active development label Jun 5, 2026

@SivanCola SivanCola left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approved. This is a well-scoped TUI fix. The PR switches the chat composer to the textarea's dynamic-height support so manual newlines and soft-wrapped pasted text expand the composer without scrolling away the first line.

Why this fits the implementation:

  • The bottom rail already sizes the transcript from m.input.Height(), so letting the textarea own visual-row height composes cleanly with the existing viewport layout.
  • The removed manual SetHeight(1) calls are covered by textarea Reset() recalculating dynamic height, while SetValue and SetWidth also recalculate height for history/rewind and resize paths.

Cache/security review:

  • No provider-visible prompt, tool schema, request serialization, compaction, dependency, network, file, command execution, or secret-handling changes.

Verified:

  • go test ./internal/cli passed
  • go test ./internal/cli -run 'Test(ManualNewline|SoftWrapped|PasteMsgFolds|TranscriptViewportSizing)' -count=1 -v passed
  • git diff --check origin/main-v2...HEAD passed

@SivanCola

Copy link
Copy Markdown
Collaborator

Related follow-up: #3054 also touches the CLI TUI bottom rail height budget for status-line wrapping. I checked the combined order locally: this PR applies cleanly first, while #3054 needs to rebase on top of this dynamic-composer shape and fix wrapped status/working-line row accounting before it can land.

@SivanCola SivanCola merged commit 5b3280a into esengine:main-v2 Jun 5, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

v2 Go rewrite (1.x) — main-v2 branch, active development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants