Skip to content

TUI: 优化交互布局与终端兼容性 - #4

Merged
boluochoufeng merged 5 commits into
boluochoufeng:mainfrom
wen227:feat/tui-polish
Jul 27, 2026
Merged

TUI: 优化交互布局与终端兼容性#4
boluochoufeng merged 5 commits into
boluochoufeng:mainfrom
wen227:feat/tui-polish

Conversation

@wen227

@wen227 wen227 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

概要

  • 重构 TUI 为无边框时间线布局,压缩工具调用与推理内容的视觉占用
  • 增加窄终端响应式布局、计划面板和审批操作的可见性保障
  • 支持 NO_COLOR、命名 ANSI 颜色及 bracketed paste,退出时可靠恢复终端状态
  • 改进多行输入:Ctrl+J 插入换行,粘贴内容规范化并保持光标语义
  • 补充不同终端尺寸、输入编辑、计划、审批、颜色和会话状态的回归测试

为什么独立提交

TUI 改动与 Provider 协议及可信配置没有实现依赖。独立 PR 可以避免扩大 Provider PR 的审核范围,并允许界面改动单独合并或回退。

验证

  • cargo fmt --all -- --check
  • cargo clippy --workspace --all-targets -- -D warnings
  • cargo check --workspace --all-targets
  • cargo test --workspace(515 passed,2 ignored:真实 DeepSeek API 测试)
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps

Copilot AI review requested due to automatic review settings July 22, 2026 12:49

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the kuncode-cli TUI rendering to a more responsive, low-noise layout, improving narrow-terminal behavior and terminal interoperability (NO_COLOR + bracketed paste), while expanding regression coverage around rendering and input editing.

Changes:

  • Reworked UI shell into header/body/plan/composer/footer panes with a Theme abstraction and improved plan/approval visibility on small terminals.
  • Updated conversation rendering to a timeline-like presentation with exact char-boundary wrapping and a scrollbar indicator.
  • Improved input UX (bracketed paste + newline insertion) and added/updated TUI regression tests; documented keybindings in the README.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
README.md Documents TUI keybindings, including multiline input and NO_COLOR behavior.
crates/kuncode-cli/src/tui/ui/conversation.rs Refactors conversation rendering (wrapping, headings, scrollbar, truncation helpers) and updates tests.
crates/kuncode-cli/src/tui/ui.rs Introduces responsive layout, Theme, plan/approval/composer rendering changes, and additional layout tests.
crates/kuncode-cli/src/tui/app/input.rs Adds atomic bracketed-paste insertion with newline normalization + tests.
crates/kuncode-cli/src/tui/app.rs Adds NO_COLOR gating, activity animation frames, and tightens approval key handling + tests.
crates/kuncode-cli/src/tui.rs Enables bracketed paste, routes paste events into the editor, and adds Ctrl+J newline support + tests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crates/kuncode-cli/src/tui/ui.rs Outdated
.iter()
.filter(|task| task.status == TodoStatus::Completed)
.count();
let inner_width = area.width.saturating_sub(2).max(1);
if approval.deny_session.is_some() {
actions.push(("d", "本次会话拒绝"));
}
actions.push(("Esc", "取消任务"));
@boluochoufeng

Copy link
Copy Markdown
Owner

Review 结论:建议先修复以下两项再合并。

  1. [P2] 异常退出不会关闭 bracketed paste

    EnableBracketedPastetui.rs:87 启用,但 DisableBracketedPaste 只会在 event_loop 正常返回后执行。发生 panic 时,ratatui 的 panic hook 仅恢复 raw mode 和 alternate screen,不会关闭 bracketed paste,可能导致返回 shell 后粘贴出现 ESC[200~ 等控制序列。建议将鼠标捕获和 bracketed paste 一并纳入 RAII guard 或自定义 panic 恢复路径。

  2. [P2] 输入恰好填满一行时光标覆盖最后一个字符

    ui.rs:307 会把等于 inner_width 的光标列 clamp 到 inner_width - 1。例如 6 格输入区中的 abcdef,光标最终落在 f 上,而不是下一视觉行开头。建议让 exact-width caret 进入新的视觉行,并让 input_height / wrapping 同步计入该行。

现有 Copilot 关于计划栏多减 2 列宽度的评论也成立,但属于较低优先级的视觉截断问题。

本地验证:cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo check --workspace --all-targetscargo test --workspacecargo doc --workspace --no-deps 均通过(515 passed,2 ignored)。

- 鼠标捕获与 bracketed paste 改由 RAII guard 管理:panic 展开时也会
  关闭,避免退回 shell 后粘贴出现 ESC[200~ 等控制序列
- 输入恰好填满一行时,光标推进到下一视觉行行首而非覆盖末字符;
  input_height 同步为该行预留高度
- 计划栏仅有顶部边框,行宽不再多减 2 列
- 审批面板不再响应未在 UI 中提示的裸 c 键;保留 Esc 与全局 Ctrl+C

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@wen227

wen227 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

已在 d23a73d 中处理全部评审意见:

  1. 异常退出不会关闭 bracketed paste — 鼠标捕获与 bracketed paste 改由 RAII guard(TerminalFeatures)管理:构造时启用、Drop 时关闭。panic 展开经过 run 时 guard 会随之析构,ratatui 的 panic hook 恢复基础终端状态后,disable 序列写入主屏幕,不会再残留粘贴/鼠标模式。

  2. exact-width 光标覆盖末字符caret_position 在列恰好到达 inner_width 时推进到下一视觉行行首(即下一个字符将渲染的位置);input_height 通过同一函数为该幻影行预留高度,滚动不会把内容顶出框外。已补充 abcd\n 不会双重换行的边界用例,以及渲染级回归测试(光标落在 f 的下一行行首而非其上)。

  3. 计划栏多减 2 列(Copilot)— draw_plan 只画顶部边框,行宽改用 area.width,并新增恰好占满全宽的计划行不被截断的测试。

  4. 审批按键与 UI 提示不一致(Copilot)— 移除裸 c 取消;保留 Esc(UI 已提示)与 Ctrl+C(全局取消惯例,弹窗打开时所有按键都路由到审批处理器,不保留会导致 Ctrl+C 失效)。已补测试。

本地验证:cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspace(518 passed, 2 ignored)、cargo doc --workspace --no-deps 均通过。

wen227 and others added 2 commits July 26, 2026 20:58
tracing 的 callsite interest 缓存是进程级全局状态:两个并行测试各自
via with_default 安装不同过滤级别的订阅器时,Dispatch 创建触发的缓存
重建窗口会让 padded_off_level_remains_disabled 偶发读到 debug 过滤器
而失败。让交换订阅器的测试共持一把互斥锁。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- PageUp/PageDown 在审批弹窗打开时仍滚动会话区:决定授权前常需回看
  上文,且鼠标滚轮本就不受弹窗影响,按键行为与之对齐
- 空闲态未绑定的 Ctrl 组合键(如 Ctrl+K)不再把字面字母插入输入框

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@wen227

wen227 commented Jul 26, 2026

Copy link
Copy Markdown
Contributor Author

补充:已用真实 DeepSeek key 对评审修复做了实机验证,并追加一个交互优化提交 5cfe126

实机验证(tmux 驱动 TUI,deepseek-v4-pro)

  • exact-width 光标:100 列终端下输入区宽 96 列。输入第 95 个字符时光标在 x=98;输入第 96 个字符后光标跳到下一视觉行行首(x=3),输入框同步长高一行,末字符不再被光标覆盖。
  • 审批按键:触发 Bash(date) 授权面板后按裸 c 无反应(面板保持),按 y 正常放行,工具执行与结果渲染完整。
  • 完整对话回路(提问 → 流式回答 → 工具审批 → 执行 → 总结)全部正常。

追加优化 5cfe126

  1. 审批弹窗打开时 PageUp/PageDown 原先被弹窗吞掉,但鼠标滚轮却能滚动会话区,行为不一致——而决定是否授权前常需要回看上文。现在滚动键在弹窗期间照常工作,y/a/n/d/Esc 不受影响。
  2. 空闲态未绑定的 Ctrl 组合键(如 Ctrl+K)原先会走 KeyCode::Char(c) 兜底分支把字面 'k' 打进输入框,现已拦截;Shift/Alt 组合仍正常输入。

均有配套测试;fmt --check / clippy -D warnings / test --workspace(520 passed)/ doc 通过。

Windows 上 crossterm 把 AltGr 上报为 LEFT_CTRL+RIGHT_ALT,欧洲键盘
布局用 AltGr 输入 @ { [ € 等字符会带 CONTROL|ALT 修饰,此前的
CONTROL 守卫会把它们静默丢弃。改为仅拦截纯 Ctrl 组合。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@boluochoufeng
boluochoufeng merged commit ceaebbc into boluochoufeng:main Jul 27, 2026
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