mirror of
https://github.com/esengine/DeepSeek-Reasonix.git
synced 2026-11-07 10:45:59 -10:00
fix(tui): preserve native terminal selection
This commit is contained in:
1 parent
9c27591edf
commit
edacf1a8c2
4 files changed
+14
-14
No files matched your search
+2
-1
@@ -213,7 +213,8 @@ Chat and transcript shortcuts:
|
||||
| `Ctrl+Home` / `Ctrl+End` | Jumps to the top or bottom of the transcript | Useful after long tool output. |
|
||||
| `Esc` | Backs out of the current action | It un-sends a just-submitted turn before any reply, cancels a running turn, or clears non-empty input. |
|
||||
| Double `Esc` on an empty idle composer | Opens the rewind picker | Same entry point as `/rewind`. |
|
||||
| `Ctrl+C` / `Meta+C` / `Super+C` | Copies an active transcript selection | Without a selection it cancels a running turn, clears non-empty input, or quits on a second empty-composer press. |
|
||||
| Terminal native selection | Copies transcript text | Reasonix does not enable mouse reporting by default, so terminal selection/copy remains available. |
|
||||
| `Ctrl+C` | Cancels, clears, or quits | Cancels a running turn, clears non-empty input, or quits on a second empty-composer press. |
|
||||
| `Ctrl+D` | Quits the TUI | Immediate quit. |
|
||||
| `Ctrl+V`, `Ctrl+Shift+V`, `Meta+V`, or `Super+V` | Pastes clipboard content | The CLI tries an image first, then falls back to text or file references. |
|
||||
| `/paste-image` | Pastes a clipboard image | Use it when you want image-only paste or the terminal handles text paste itself. |
|
||||
|
||||
+2
-1
@@ -194,7 +194,8 @@ Goal、由 `todo_write` 工具驱动的实时 Todo 面板,以及已配置 prov
|
||||
| `Ctrl+Home` / `Ctrl+End` | 跳到 transcript 顶部或底部 | 长工具输出后很有用。 |
|
||||
| `Esc` | 退出当前最具体的动作 | 可在无回复前撤回刚提交的 turn、取消运行中的 turn,或清空非空输入。 |
|
||||
| 空闲且输入为空时双击 `Esc` | 打开 rewind 选择器 | 和 `/rewind` 是同一个入口。 |
|
||||
| `Ctrl+C` / `Meta+C` / `Super+C` | 复制当前 transcript 选区 | 没有选区时用于取消运行中 turn、清空非空输入;空输入下连按两次退出。 |
|
||||
| 终端原生选择 | 复制 transcript 文本 | Reasonix 默认不启用鼠标报告,因此终端自己的选择/复制仍可使用。 |
|
||||
| `Ctrl+C` | 取消、清空或退出 | 取消运行中的 turn、清空非空输入;空输入下连按两次退出。 |
|
||||
| `Ctrl+D` | 退出 TUI | 立即退出。 |
|
||||
| `Ctrl+V`、`Ctrl+Shift+V`、`Meta+V` 或 `Super+V` | 粘贴剪贴板内容 | CLI 会先尝试图片,再回退到文本或文件引用。 |
|
||||
| `/paste-image` | 粘贴剪贴板图片 | 适合只想贴图片,或终端应用自己接管文本粘贴的场景。 |
|
||||
|
||||
@@ -38,9 +38,9 @@ import (
|
||||
)
|
||||
|
||||
// chatTUI is a bubbletea Model that normally owns the terminal with an
|
||||
// alt-screen transcript viewport. Termux is the exception: enabling mouse mode
|
||||
// prevents taps from raising the soft keyboard, so it stays in the normal buffer
|
||||
// and commits finalized output to native scrollback via tea.Println.
|
||||
// alt-screen transcript viewport. Termux is the exception: it stays in the
|
||||
// normal buffer and commits finalized output to native scrollback via
|
||||
// tea.Println so taps can still focus the soft keyboard.
|
||||
type chatTUI struct {
|
||||
ctrl control.SessionAPI
|
||||
label string
|
||||
@@ -48,8 +48,8 @@ type chatTUI struct {
|
||||
|
||||
width int
|
||||
height int
|
||||
// nativeScrollback keeps Termux out of alt-screen/mouse mode so taps still
|
||||
// focus the textarea and raise the soft keyboard.
|
||||
// nativeScrollback keeps Termux out of alt-screen mode so taps still focus
|
||||
// the textarea and raise the soft keyboard.
|
||||
nativeScrollback bool
|
||||
|
||||
input textarea.Model
|
||||
@@ -1375,8 +1375,7 @@ func (m chatTUI) update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
||||
// finalize drains the committed-line queue and batches the turn's commands. In
|
||||
// the default alt-screen path the queue is already mirrored in m.transcript. In
|
||||
// Termux we cannot enable mouse mode without breaking soft-keyboard focus, so
|
||||
// finalized lines are also emitted into the terminal's native scrollback.
|
||||
// Termux finalized lines are also emitted into the terminal's native scrollback.
|
||||
func finalize(m chatTUI, cmds []tea.Cmd) tea.Cmd {
|
||||
if m.nativeScrollback && len(*m.pendingCommit) > 0 {
|
||||
out := strings.TrimRight(clampWidth(strings.Join(*m.pendingCommit, "\n"), m.width), "\n")
|
||||
@@ -2399,7 +2398,6 @@ func (m chatTUI) View() tea.View {
|
||||
}
|
||||
v := tea.NewView(mainArea + "\n" + strings.Join(parts, "\n"))
|
||||
v.AltScreen = true
|
||||
v.MouseMode = tea.MouseModeCellMotion // wheel scrolls the transcript
|
||||
// Anchor the real terminal cursor at the textarea's insertion point only when
|
||||
// the composer is visible. input.Cursor() is relative to the textarea; offset
|
||||
// by the viewport height + rows above + the box's top border row (+1 column
|
||||
|
||||
@@ -1392,8 +1392,8 @@ func TestQueueIndicatorHiddenWhenIdle(t *testing.T) {
|
||||
}
|
||||
|
||||
// TestViewAltScreenFillsHeight proves the switch to alt-screen: View requests
|
||||
// the alt buffer + mouse, and the frame is exactly the terminal height (the
|
||||
// transcript viewport pads to fill above the pinned bottom region).
|
||||
// the alt buffer without mouse reporting, and the frame is exactly the terminal
|
||||
// height (the transcript viewport pads to fill above the pinned bottom region).
|
||||
func TestViewAltScreenFillsHeight(t *testing.T) {
|
||||
ctrl := control.New(control.Options{})
|
||||
m := newChatTUI(ctrl, "", make(chan event.Event, 1), 80)
|
||||
@@ -1404,8 +1404,8 @@ func TestViewAltScreenFillsHeight(t *testing.T) {
|
||||
if !v.AltScreen {
|
||||
t.Error("View must request alt-screen so resize repaints the whole grid")
|
||||
}
|
||||
if v.MouseMode != tea.MouseModeCellMotion {
|
||||
t.Error("View must enable mouse so the wheel scrolls the transcript")
|
||||
if v.MouseMode != tea.MouseModeNone {
|
||||
t.Error("View must leave terminal mouse selection available by default")
|
||||
}
|
||||
if lines := strings.Count(v.Content, "\n") + 1; lines != 24 {
|
||||
t.Errorf("alt-screen frame = %d lines, want 24 (full terminal height)", lines)
|
||||
|
||||
Reference in new issue
Block a user