# 機能設計書 59-ターミナル操作

## 概要

本ドキュメントは、Nushellにおけるターミナル操作機能の設計仕様を記載する。この機能は、term size、term query、clear、input、input listなどのコマンドを通じてターミナルの情報取得・制御・ユーザー入力取得を提供する。

### 本機能の処理概要

ターミナル操作機能は、ターミナルエミュレーターとの対話的な操作を可能にし、画面サイズ取得、画面クリア、ユーザー入力の取得などを行う。

**業務上の目的・背景**：対話型スクリプトやTUIアプリケーションの構築において、ターミナルの状態取得やユーザー入力処理は不可欠である。Nushellの構造化データ処理と統合することで、高度な対話型ツールの開発を可能にする。

**機能の利用シーン**：
- ターミナルサイズに応じた出力フォーマット調整
- ユーザーへの確認プロンプト表示
- メニュー選択インターフェースの構築
- 画面のリフレッシュ・クリア
- インタラクティブなスクリプト実行

**主要な処理内容**：
1. term sizeでターミナルの列数・行数を取得
2. clearで画面とスクロールバック履歴をクリア
3. inputでユーザーからの文字列入力を取得
4. input listでメニュー形式の選択肢を提示

**関連システム・外部連携**：
- ターミナルエミュレーター
- crosstermライブラリ（ターミナル制御）
- reedlineライブラリ（入力処理）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLI専用コマンド |

## 機能種別

ターミナル制御 / ユーザー入力

## 入力仕様

### 入力パラメータ

#### term size

パラメータなし

#### clear

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --keep-scrollback, -k | Switch | No | スクロールバック履歴を保持 | - |

#### input

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| prompt | String | No | 表示するプロンプト | - |
| --bytes-until-any, -u | String | No | 停止バイトまで読み込み | - |
| --numchar, -n | Int | No | 読み込む文字数 | - |
| --default, -d | String | No | デフォルト値 | - |
| --reedline | Switch | No | reedlineモードで入力 | - |
| --history-file | Filepath | No | 履歴ファイルのパス | - |
| --max-history | Int | No | 履歴の最大エントリ数 | - |
| --suppress-output, -s | Switch | No | キー入力を表示しない | - |

### 入力データソース

コマンドライン引数、パイプライン入力（input listの選択肢）

## 出力仕様

### 出力データ

#### term size

| 項目名 | 型 | 説明 |
|--------|-----|------|
| columns | Int | 列数（幅） |
| rows | Int | 行数（高さ） |

#### clear

出力なし

#### input

| 項目名 | 型 | 説明 |
|--------|-----|------|
| (出力) | String | ユーザーが入力した文字列 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス（term size）

```
1. サイズ取得
   └─ crossterm::terminal::size()でサイズ取得
2. レコード構築
   └─ columns, rowsのレコードを構築
3. 結果返却
   └─ Recordとして返却
```

### 処理シーケンス（clear）

```
1. フラグ確認
   └─ --keep-scrollbackの確認
2. 画面クリア
   ├─ カーソルを(0,0)に移動
   ├─ 画面全体をクリア
   └─ (--keep-scrollbackなし) スクロールバックをパージ
3. フラッシュ
   └─ stdoutをフラッシュ
```

### 処理シーケンス（input）

```
1. モード判定
   └─ --reedline / 履歴ファイル / レガシーモードを判定
2. プロンプト構築
   └─ デフォルト値表示を含むプロンプト
3. 入力取得
   ├─ reedline: Reedline::read_line()
   └─ legacy: 直接stdin読み取り
4. 結果処理
   └─ デフォルト値適用、String返却
```

### フローチャート

```mermaid
flowchart TD
    A[term size実行] --> B[crossterm::terminal::size]
    B --> C[Record構築]
    C --> D[結果返却]

    E[clear実行] --> F{--keep-scrollback?}
    F -->|Yes| G[画面クリアのみ]
    F -->|No| H[画面+スクロールバッククリア]
    G --> I[stdout flush]
    H --> I

    J[input実行] --> K{モード}
    K -->|reedline| L[Reedline入力]
    K -->|legacy| M[stdin読み取り]
    L --> N[Signal処理]
    M --> N
    N --> O{入力あり?}
    O -->|Yes| P[文字列返却]
    O -->|No| Q[デフォルト値返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | サイズ取得失敗時 | (0, 0)を返却 | size()失敗時 |
| BR-02 | デフォルトスクロールバック | デフォルトでスクロールバックもクリア | clear実行時 |
| BR-03 | Ctrl+C処理 | 割り込みエラーを返却 | input中のCtrl+C |
| BR-04 | Ctrl+D処理 | Nothingを返却 | input中のCtrl+D |
| BR-05 | 空入力デフォルト | 空文字列の場合はデフォルト値を使用 | --defaultあり時 |

### 計算ロジック

特になし

## データベース操作仕様

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| IoError | I/Oエラー | ターミナル操作失敗 | ターミナル環境を確認 |
| IoError (Interrupted) | 割り込み | Ctrl+C | 正常な割り込み処理 |
| IncorrectValue | 引数エラー | 無効な履歴ファイル | パスを確認 |

### リトライ仕様

該当なし

## トランザクション仕様

該当なし

## パフォーマンス要件

特になし（即座に完了）

## セキュリティ考慮事項

- inputコマンドでパスワード入力時は--suppress-outputを使用推奨
- 履歴ファイルに機密情報が保存される可能性あり

## 備考

- crosstermライブラリでクロスプラットフォーム対応
- input listはfuzzy matcherによるフィルタリング対応

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | term_size.rs | `crates/nu-command/src/platform/term/term_size.rs` | term sizeの出力構造 |

**読解のコツ**:
- **17-22行目**: 出力型として{columns: Int, rows: Int}のRecordを定義

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | term_size.rs | `crates/nu-command/src/platform/term/term_size.rs` | term sizeの実装 |
| 2-2 | clear.rs | `crates/nu-command/src/platform/clear.rs` | clearの実装 |
| 2-3 | input_.rs | `crates/nu-command/src/platform/input/input_.rs` | inputの実装 |

**主要処理フロー（term_size.rs）**:
- **45-63行目**: run()でcrossterm::terminal::size()を呼び出しRecord返却

**主要処理フロー（clear.rs）**:
- **38-67行目**: run()でカーソル移動とクリア実行
- **46-54行目**: --keep-scrollbackフラグによる処理分岐
- **56-66行目**: スクロールバックのパージ（Purge）

**主要処理フロー（input_.rs）**:
- **73-95行目**: run()でモード判定（reedline vs legacy）
- **97-162行目**: reedlineモードでの履歴・プロンプト設定
- **170-209行目**: Reedline::read_line()での入力取得

#### Step 3: reedline統合を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | input_.rs | `crates/nu-command/src/platform/input/input_.rs` | reedlineとの統合 |

**主要処理フロー**:
- **119-161行目**: FileBackedHistoryの設定
- **164-168行目**: ReedlinePromptの構築
- **170-175行目**: Reedline::create()とカスタマイズ
- **179-181行目**: prefill_reedline_buffer()でデフォルト値設定
- **185-205行目**: read_line()結果のSignal処理

### プログラム呼び出し階層図

```
term size コマンド
    │
    └─ run()
           └─ crossterm::terminal::size()
                  └─ Record { columns, rows }

clear コマンド
    │
    └─ run()
           ├─ stdout.queue(MoveTo(0, 0))
           ├─ stdout.queue(Clear(ClearType::All))
           ├─ [--keep-scrollback なし] stdout.queue(Clear(ClearType::Purge))
           └─ stdout.flush()

input コマンド
    │
    └─ run()
           │
           ├─ [reedline mode]
           │      ├─ FileBackedHistory設定
           │      ├─ ReedlinePrompt構築
           │      ├─ Reedline::create()
           │      ├─ prefill_reedline_buffer()
           │      └─ read_line()
           │
           └─ [legacy mode]
                  └─ legacy_input() (stdin直接読み取り)
```

### データフロー図

```
[入力]                    [処理]                         [出力]

(なし) ─────────────────▶ term size ────────────────────▶ Record { columns, rows }

--keep-scrollback ──────▶ clear ────────────────────────▶ Nothing
                         ターミナルANSIエスケープ

prompt + options ───────▶ input ────────────────────────▶ String
                         Reedline / stdin読み取り
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| term_size.rs | `crates/nu-command/src/platform/term/term_size.rs` | ソース | term sizeコマンド |
| term_query.rs | `crates/nu-command/src/platform/term/term_query.rs` | ソース | term queryコマンド |
| term_.rs | `crates/nu-command/src/platform/term/term_.rs` | ソース | termコマンド（ヘルプ） |
| clear.rs | `crates/nu-command/src/platform/clear.rs` | ソース | clearコマンド |
| input_.rs | `crates/nu-command/src/platform/input/input_.rs` | ソース | inputコマンド |
| list.rs | `crates/nu-command/src/platform/input/list.rs` | ソース | input listコマンド |
| input_listen.rs | `crates/nu-command/src/platform/input/input_listen.rs` | ソース | input listenコマンド |
| reedline_prompt.rs | `crates/nu-command/src/platform/input/reedline_prompt.rs` | ソース | Reedlineプロンプト |
