172 lines
9.9 KiB
Markdown
172 lines
9.9 KiB
Markdown
# TUI キーバインド
|
||
|
||
`crates/tui` の対話画面で効くキー一覧。`crates/tui/src/main.rs:handle_key` を単一情報源とし、このドキュメントは人間向けの目次。
|
||
|
||
## 入力編集
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| 文字キー | カーソル位置に挿入(未割り当ての `Ctrl`+文字キーは無視) |
|
||
| `Ctrl-A` | 入力欄全体の先頭へ |
|
||
| `Backspace` | カーソル直前を削除(ペーストプレースホルダは 1 回で全削除) |
|
||
| `Delete` | カーソル直後を削除(同上) |
|
||
| `Left` / `Right` | カーソル移動 |
|
||
| `Up` / `Down` | 通常は論理行単位の上下移動。入力欄の先頭/末尾では送信済み composer history を browse |
|
||
| `Home` / `End` | 現在行の行頭 / 行末へ |
|
||
| `Alt-Enter` | 改行を挿入(Input を複数行化) |
|
||
| `Esc` | completion popup があれば閉じる |
|
||
|
||
### ペーストプレースホルダ
|
||
|
||
ブラケットペーストで入力されたテキストは入力バッファ上では不可分な
|
||
プレースホルダ `[Clipboard #N | X chars, Y lines]` として表示される。
|
||
実テキストは裏で保持され、送信時に `#N` ラベル無しで展開されて Pod に渡る。
|
||
カーソルはプレースホルダ内部には入れず、`Backspace` / `Delete` 1 回で
|
||
プレースホルダ全体が消える。`#N` の通し番号は TUI プロセス起動中で連番。
|
||
|
||
### Completion
|
||
|
||
`@` file ref / `#` knowledge ref / `/` workflow invocation などは completion popup を開く。
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| `Up` / `Down` | completion 候補を移動 |
|
||
| `Tab` | 選択候補をテキストとして適用 |
|
||
| `Enter` | committable な候補は chip 化して空白を追加。directory などはテキスト適用して drill-in |
|
||
| `Esc` | popup を閉じる |
|
||
| 空白文字 | exact match なら chip 化してから空白を挿入 |
|
||
|
||
## 送信(Enter)
|
||
|
||
| 状態 | 入力あり | 入力空 |
|
||
|---|---|---|
|
||
| Idle | `Method::Run` で新ターン開始 | no-op |
|
||
| Paused | `Method::Run`(前ターンは割り込み終了として扱い、新ターンとして開始) | `Method::Resume`(前ターンの続きを再開) |
|
||
| Running | 入力は TUI 側 queue に積まれ、現在 turn の終了後に自動送信 | no-op |
|
||
|
||
### Running 中の queue
|
||
|
||
Running 中に入力ありで Enter すると、現在の provider stream には割り込まず、typed input segments を TUI-local queue に積む。`RunResult::Finished` / `LimitReached` 後に先頭の queued input が次の `Method::Run` として自動送信される。`Paused` / `RolledBack` では自動送信しない。
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| `Alt-Q` | queue 先頭を composer に戻す(composer が空の時のみ) |
|
||
| `Alt-C` | queued input を全消去 |
|
||
|
||
### Paused からの挙動
|
||
|
||
Paused 中に Enter すると、入力の有無で 2 通り:
|
||
|
||
- **空**: 前ターンを中断した地点から **Resume**。LLM はそのまま続きを書く(partial text は破棄済み)、未実行の tool があれば実行して続行
|
||
- **入力あり**: 前ターンは「割り込み終了」扱いとなり、新ターンとして **Run**。Pod 側では
|
||
1. 未応答 `tool_use` があれば synthetic `tool_result("[Interrupted by user]")` で閉じる
|
||
2. `[The previous turn was interrupted by the user]` system note を履歴に挿入
|
||
3. 入力を新しい user メッセージとして append
|
||
4. ターン開始
|
||
|
||
## Command mode
|
||
|
||
composer が空の通常入力で `:` を押すと command mode に入る。command mode 中は composer が command line として扱われる。
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| `Enter` | command を実行 |
|
||
| `Esc` | command mode を終了 |
|
||
| `Backspace` | 文字を削除。空なら command mode を終了 |
|
||
| `Ctrl-U` | command input をクリア |
|
||
| `Tab` | command completion を適用 |
|
||
| `Up` / `Down` | command completion 候補があれば移動、なければカーソル上下 |
|
||
|
||
主な command は `:help`, `:noop`, `:compact`, `:rewind` / `:rollback`。`:compact` は idle 時だけ即時 compaction を要求し、`:rewind` / `:rollback` は rewind target picker を開く。
|
||
|
||
## 履歴ビューのナビゲーション
|
||
|
||
履歴ビューは全画面 TUI の上段にあり、TUI 内部で全ブロックを state として
|
||
保持してスクロール可能。スクロールバック(端末側の履歴)ではなく TUI の
|
||
自前バッファを動かす点に注意。
|
||
|
||
| キー / 操作 | 動作 |
|
||
|---|---|
|
||
| `Shift-Up` / `Shift-Down` | 1 論理行スクロール |
|
||
| mouse wheel | 数行単位でスクロール |
|
||
| `PageUp` / `PageDown` | 1 ページスクロール(task pane が開いている時は task pane をスクロール) |
|
||
| `Ctrl-[` / `Ctrl-]` | 前 / 次のターン先頭へジャンプ |
|
||
| `Ctrl-Home` | 履歴の先頭へ |
|
||
| `Ctrl-End` | 履歴の末尾へ(末尾追従モードを再開) |
|
||
|
||
### 末尾追従
|
||
|
||
デフォルトは「末尾追従」モード:新しいイベント到着で自動的に最新行が
|
||
画面下に固定される。ユーザーが上方向にスクロールした瞬間に追従は解除され、
|
||
その位置で固定される(新着イベントが来ても画面は動かない)。再び追従に
|
||
戻すには `Ctrl-End`。追従解除中はステータスバー右に `↑ scrolled` が点く。
|
||
|
||
### ターン単位ジャンプ
|
||
|
||
`Ctrl-[` / `Ctrl-]` は TurnHeader ブロックの位置にスクロールオフセットを
|
||
合わせる。多数のツール呼び出しが挟まった長いターンでも前後ターンの先頭に
|
||
1 発で戻れる。末尾ターンから `Ctrl-]` を押すと末尾追従に復帰する。
|
||
|
||
## 表示モード / 補助 pane
|
||
|
||
履歴各ブロックの密度を 3 段階で切り替える。現在のモードはステータスバー
|
||
右端に `[mode]` として表示される。
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| `Ctrl-O` | `detail` → `normal` → `overview` → `detail` の順に循環 |
|
||
| `Ctrl-T` | task pane を開閉 |
|
||
|
||
- **detail**: 全ブロック完全表示。ツールブロックは結果本体も全量
|
||
- **normal**: 完了ブロックは概ね 5–6 行に圧縮、実行中のツールブロックは detail と同じ扱い
|
||
- **overview**: 各ブロック 1 行に畳む(ツールブロックは `ToolResult.summary` 1 行、長文 AssistantText は先頭 1 行 + 省略記)
|
||
|
||
モード切替は全体に一括適用。個別ブロックの開閉は持たない。
|
||
|
||
## Pod 制御
|
||
|
||
| キー | Running 中 | Idle / Paused |
|
||
|---|---|---|
|
||
| `Ctrl-X` | queued input を消去して `Method::Cancel`(進行中ターンを破棄 → Idle) | `Method::Shutdown`(Pod を終了) |
|
||
| `Ctrl-C` | `Method::Pause`(進行中ターンを中断 → Paused) | 1 回目 warn、3 秒以内の 2 回目で TUI 終了(Pod は残る) |
|
||
| `Ctrl-D` | TUI 終了(Pod は残る、Pause しない) | TUI 終了(Pod は残る) |
|
||
| `Ctrl-R` | rewind picker 要求は拒否される | rewind target picker を開く |
|
||
|
||
### Cancel と Pause の違い
|
||
|
||
- **Cancel** は「ターンを捨てる」: 進行中の LLM リクエスト・未完了 tool を打ち切り、状態は Idle。続きは Resume できない
|
||
- **Pause** は「止めるけど続けられるように」: 同じく打ち切るが状態は Paused、空 Enter で Resume 可能
|
||
|
||
Running 中に割り込みたい場合、ほとんどのケースで `Ctrl-C`(Pause)が自然。Ctrl-X(Cancel)は明示的に破棄したい時(LLM が暴走した時など)用。Pod を終了したい場合は、先に Running ではない状態(Idle / Paused)にしてから `Ctrl-X` で Shutdown する。
|
||
|
||
### Rewind picker
|
||
|
||
`Ctrl-R` または `:rewind` / `:rollback` で Pod に `Method::ListRewindTargets` を送り、main area に rewind target picker を開く。picker 中の操作は以下。
|
||
|
||
| キー | 動作 |
|
||
|---|---|
|
||
| `Up` / `Down` | target を移動 |
|
||
| `Enter` | 選択 target へ `Method::RewindTo`。復元された user input は composer に戻る |
|
||
| `Esc` | picker を閉じる |
|
||
|
||
Running 中の rewind request は拒否される。Paused 中は picker を開けるが、実際の apply は idle で composer が空の時だけ行う。
|
||
|
||
### Ctrl-C と Ctrl-D の終了 UX
|
||
|
||
- Ctrl-X Running 中: queued input を消去して `Method::Cancel`。終了したい場合は、明示的にターンを止めて Idle に戻してからもう一度 `Ctrl-X`
|
||
- Ctrl-X Idle / Paused: `Method::Shutdown` を送って Pod を終了
|
||
- Ctrl-C Running 中: 1 回目で即 Pause(破壊的ではない)
|
||
- Ctrl-C Idle / Paused: 1 回目で warn メッセージ、3 秒以内の 2 回目で TUI 終了(Pod は残る)
|
||
- Ctrl-D: 状態に関わらず即 TUI 終了(Pod は残る)。Running 中でも Pause / Cancel / Shutdown は送らない
|
||
|
||
`Ctrl-X` は Running 中だけ Cancel、Idle / Paused では Shutdown。`Ctrl-C` は Running 中だけ Pod に `Method::Pause` を送り、それ以外では Pod は落とさず TUI プロセスだけ抜ける。`Ctrl-D` は常に Pod へ制御メソッドを送らず TUI プロセスだけ抜ける。
|
||
|
||
TUI のダイアログから Pod を起動する経路では、起動した Pod は TUI の子プロセスとして管理・終了されず、独立したプロセスとして残る。TUI 終了後は `yoi <pod-name>` で再接続できる。
|
||
|
||
## 履歴メモ
|
||
|
||
- `Ctrl-R` はかつて Resume 専用だったが、空 Enter での Resume に統合された。現在の `Ctrl-R` は rewind picker の導線
|
||
- かつて存在した `Esc`(TUI 終了)は、`Ctrl-C` の 2 連打 UX に統合されたため廃止。現在の `Esc` は popup / picker / command mode のキャンセル用途
|
||
- かつて `Ctrl-D` は Pod に `Method::Shutdown` を送っていたが、TUI だけを抜けるデタッチ操作に変更された
|
||
- 旧 inline viewport 時代は履歴スクロールを端末側スクロールバックに任せていたため TUI 内のスクロールキーは存在しなかった。全画面 alt screen への移行で `Shift-Up/Down` ほかのナビゲーションキーが追加された
|