# 画面設計書 1-メインREPL

## 概要

本ドキュメントは、Nushellの中核となるメインREPL（Read-Eval-Print Loop）画面の設計仕様を定義する。REPLはユーザーがNushellと対話するための主要インターフェースであり、コマンド入力、パイプライン実行、結果表示を行う対話型シェル環境を提供する。

### 本画面の処理概要

メインREPL画面は、Nushellシェルの対話的な操作環境を提供する画面である。ユーザーはこの画面でコマンドを入力し、即座に実行結果を確認できる。

**業務上の目的・背景**：
従来のシェル（bash, zsh等）とは異なり、Nushellは構造化データ（テーブル、レコード、リスト等）をネイティブにサポートする。メインREPLはこの構造化データ処理の入り口として、ユーザーがコマンドを入力し、パイプラインを構築し、データを変換・分析するための中心的なインターフェースを提供する。また、シンタックスハイライト、補完、履歴管理などのリッチな編集機能により、効率的なシェル操作を実現する。

**画面へのアクセス方法**：
- ターミナルエミュレータでNushellを起動（`nu`コマンド実行）
- Nushell起動時に自動的にREPL画面が表示される
- 標準入力がTTYに接続されていることが必須条件

**主要な操作・処理内容**：
1. コマンド入力：キーボードからNushellコマンドを入力
2. Tab補完：コマンド名、パス、変数等の自動補完
3. シンタックスハイライト：入力中のコマンドを色分け表示
4. コマンド実行：Enterキーでパイプラインを実行
5. 結果表示：構造化データのテーブル形式表示
6. 履歴検索：過去のコマンド履歴を検索・再利用
7. Auto-cd：ディレクトリパスを入力するだけでcd実行
8. プロンプトカスタマイズ：左右プロンプト、vi mode表示

**画面遷移**：
- Tab押下 → 補完メニュー（画面No.2）
- F1等押下 → ヘルプ補完メニュー（画面No.3）
- `explore`コマンド実行 → Exploreビュー（画面No.4, 5, 6）
- `--lsp`オプション起動 → LSP言語サーバ（画面No.10）
- `exit`またはCtrl+D → シェル終了

**権限による表示制御**：
- 特になし。全ユーザーが同一の機能を利用可能

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | シェル実行環境 | 主機能 | コマンド入力・パイプライン実行・構造化データ処理の主処理を担当 |
| 2 | パーサー | 主機能 | 入力されたコマンドの構文解析・型チェックをリアルタイムで実行 |
| 56 | 環境変数 | 補助機能 | REPL実行中の環境変数管理（CMD_DURATION_MS等） |
| 84 | REPL | 主機能 | reedlineライブラリを使用した対話型シェル環境の提供 |
| 85 | 補完機能 | 補助機能 | タブキー押下時のコマンド・パス・変数の自動補完処理 |
| 86 | シンタックスハイライト | 補助機能 | コマンド入力中の構文に応じた色付け表示 |
| 87 | プロンプト | 補助機能 | カスタマイズ可能なプロンプト表示（左右・vi mode対応） |
| 88 | 履歴管理 | 補助機能 | コマンド履歴の保存・検索・同期（SQLite/テキストベース） |
| 89 | 設定管理 | 補助機能 | shell_integration等の設定値参照・反映 |
| 57 | 外部コマンド実行 | API連携 | 外部コマンド（^）の実行とパイプライン連携 |

## 画面種別

対話型シェル（REPL - Read-Eval-Print Loop）

## URL/ルーティング

N/A（CLI/TUIアプリケーションのためURL概念なし）

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| コマンドライン | String | 入力 | ユーザーが入力するNushellコマンド |
| 環境変数 | Record | 入出力 | シェル実行環境の環境変数 |
| 作業ディレクトリ | Path | 入出力 | 現在の作業ディレクトリ（PWD） |
| パイプライン出力 | PipelineData | 出力 | コマンド実行結果（Value, List, Record等） |
| 終了コード | Int | 出力 | 直前のコマンドの終了コード（LAST_EXIT_CODE） |
| コマンド実行時間 | Duration | 出力 | 直前のコマンドの実行時間（CMD_DURATION_MS） |

## 表示項目

| 項目名 | 説明 | 表示形式 |
|--------|------|----------|
| 左プロンプト | カレントディレクトリ等を表示 | カスタマイズ可能な文字列 |
| 右プロンプト | 時刻・ブランチ名等を表示 | カスタマイズ可能な文字列 |
| 入力行 | ユーザーの入力テキスト | シンタックスハイライト付き |
| ヒント | 履歴ベースの入力補完候補 | 薄い色で表示 |
| 実行結果 | コマンド出力 | テーブル/レコード/テキスト形式 |
| エラーメッセージ | パースエラー・実行エラー | エラー詳細とスパン情報 |

## イベント仕様

### 1-Enter押下（コマンド実行）

1. 入力バッファのテキストを取得
2. パーサーでAST（抽象構文木）に変換
3. Auto-cd判定（単一ディレクトリパスの場合）
4. pre_executionフックを実行
5. エンジンでパイプラインを評価・実行
6. 結果をフォーマットして表示
7. 履歴に保存
8. 環境変数（CMD_DURATION_MS, LAST_EXIT_CODE）を更新
9. プロンプトを再描画

### 2-Tab押下（補完）

1. 現在のカーソル位置でパース
2. コンテキストに応じた補完候補を生成（コマンド/パス/変数等）
3. 補完メニューを表示
4. 選択された候補を入力バッファに挿入

### 3-Ctrl+D（終了）

1. cleanup_exit関数を呼び出し
2. 必要に応じてexit_hooksを実行
3. シェルプロセスを終了

### 4-Auto-cd（パス直接入力）

1. 入力がディレクトリパスかどうかを判定
2. パスが存在し、アクセス可能か確認
3. PWD環境変数を更新
4. OLDPWD、NUSHELL_SHELLSを更新

## データベース更新仕様

### 操作別データベース影響一覧

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| コマンド実行 | history（SQLite） | INSERT | コマンド履歴の保存 |
| コマンド実行 | history（SQLite） | UPDATE | 実行時間・終了コードの記録 |
| 履歴同期 | history（SQLite） | SELECT | 他セッションの履歴を取得 |

### テーブル別更新項目詳細

#### history（SQLiteBackedHistory使用時）

| 操作 | 項目（カラム名） | 更新値・取得条件 | 備考 |
|-----|-----------------|-----------------|------|
| INSERT | command_line | 実行したコマンド文字列 | |
| INSERT | start_timestamp | コマンド実行開始時刻 | |
| INSERT | hostname | システムのホスト名 | |
| INSERT | cwd | 実行時のカレントディレクトリ | |
| UPDATE | duration | コマンド実行時間 | 実行完了後に更新 |
| UPDATE | exit_status | LAST_EXIT_CODE値 | 実行完了後に更新 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| TTY_ERROR | エラー | Nushell launched as a REPL, but STDIN is not a TTY | 標準入力がTTYでない |
| PARSE_ERROR | エラー | パースエラーの詳細 | 構文エラー時 |
| SHELL_ERROR | エラー | シェルエラーの詳細 | 実行時エラー |
| PERMISSION_DENIED | エラー | Cannot change directory | Auto-cdで権限不足 |
| DIRECTORY_NOT_FOUND | エラー | Cannot change directory | Auto-cdでパス不存在 |
| END_MSG | 情報 | （改行のみ） | Ctrl+Dで終了時 |

## 例外処理

| 例外状態 | 対応処理 |
|---------|---------|
| TTYでない | エラーメッセージを表示して終了 |
| パースエラー | エラーをreport_shell_errorで表示、REPLは継続 |
| 実行エラー | エラーをreport_shell_errorで表示、REPLは継続 |
| パニック | catch_unwindでキャッチし、直前の状態にロールバック、line_editorを再構築 |
| 履歴同期失敗 | 警告ログを出力、REPLは継続 |

## 備考

- reedlineライブラリを使用したリッチなライン編集機能を提供
- Kittyプロトコル対応による高度なキーボード入力サポート
- OSC 133/633シェル統合によるVSCode等との連携
- EmacsモードとViモードの両方をサポート
- 設定ファイル（config.nu）によるカスタマイズ可能

---

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

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

### 推奨読解順序

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

REPLで扱う主要なデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | engine_state.rs | `crates/nu-protocol/src/engine/engine_state.rs` | EngineStateの構造（環境変数、宣言、スコープ） |
| 1-2 | stack.rs | `crates/nu-protocol/src/engine/stack.rs` | Stackの構造（ローカル変数、環境変数差分） |
| 1-3 | value.rs | `crates/nu-protocol/src/value/mod.rs` | Value型の種類（Record, List, String等） |

**読解のコツ**: EngineStateは不変の共有状態、Stackは可変のローカル状態と理解する

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

REPLループの起点となる関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | repl.rs | `crates/nu-cli/src/repl.rs` | evaluate_repl関数がREPLのメインエントリーポイント |

**主要処理フロー**:
1. **70-249行**: `evaluate_repl`関数 - REPLの初期化とメインループ
2. **104行**: `get_line_editor` - reedlineの初期化
3. **187-246行**: メインループ - loop_iterationを繰り返し呼び出し
4. **320-772行**: `loop_iteration`関数 - 1回のREPL反復処理

#### Step 3: ループ反復処理を理解する

各REPL反復で行われる処理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | repl.rs | `crates/nu-cli/src/repl.rs` | loop_iteration関数の処理フロー |

**主要処理フロー**:
- **339-342行**: 環境変数のマージ
- **351-357行**: env_changeフックの実行
- **362-370行**: pre_promptフックの実行
- **394-436行**: line_editorの設定（ハイライター、補完、バリデーター）
- **501-512行**: プロンプトの更新
- **520行**: `line_editor.read_line` - ユーザー入力の待機
- **546-758行**: 入力シグナルの処理（Success/CtrlC/CtrlD/Error）
- **633行**: `parse_operation` - 入力の解析
- **647-663行**: `do_run_cmd` - コマンドの実行

#### Step 4: コマンド実行処理を理解する

パイプラインの評価と実行を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | repl.rs | `crates/nu-cli/src/repl.rs` | do_run_cmd関数 |
| 4-2 | eval_source.rs | `crates/nu-cli/src/util.rs` | eval_source関数 |

**主要処理フロー**:
- **964-1021行**: `do_run_cmd` - コマンド実行のラッパー
- **1003-1010行**: `eval_source` - ソースコードの評価

#### Step 5: 補完機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | completer.rs | `crates/nu-cli/src/completions/completer.rs` | NuCompleter構造体とfetch_completions_at関数 |
| 5-2 | command_completions.rs | `crates/nu-cli/src/completions/command_completions.rs` | コマンド名補完 |
| 5-3 | file_completions.rs | `crates/nu-cli/src/completions/file_completions.rs` | ファイルパス補完 |

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

```
main()
    |
    +-- evaluate_repl()                  [crates/nu-cli/src/repl.rs:70]
            |
            +-- get_line_editor()        [crates/nu-cli/src/repl.rs:288]
            |       +-- Reedline::create()
            |       +-- setup_history()  [crates/nu-cli/src/repl.rs:1195]
            |
            +-- loop_iteration()         [crates/nu-cli/src/repl.rs:320]
                    |
                    +-- engine_state.merge_env()
                    |
                    +-- hook::eval_env_change_hook()
                    |
                    +-- hook::eval_hooks() (pre_prompt)
                    |
                    +-- prompt_update::update_prompt()
                    |
                    +-- line_editor.read_line()
                    |
                    +-- parse_operation()     [crates/nu-cli/src/repl.rs:849]
                    |       +-- lex()
                    |       +-- looks_like_path()
                    |
                    +-- do_auto_cd()          [crates/nu-cli/src/repl.rs:882]
                    |   or
                    +-- do_run_cmd()          [crates/nu-cli/src/repl.rs:964]
                            +-- eval_source()
                                    +-- parse()
                                    +-- eval_block()
```

### データフロー図

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

ユーザー入力 ──────────▶ Reedline
     │                     │
     │                     ▼
     │              NuHighlighter ──────────────▶ 色付き表示
     │                     │
     │              NuCompleter ────────────────▶ 補完候補
     │                     │
     ▼                     ▼
コマンド文字列 ────────▶ parse()
                           │
                           ▼
                         AST
                           │
                           ▼
                      eval_block()
                           │
                           ▼
                    PipelineData ──────────────▶ テーブル/テキスト出力
                           │
                           ▼
                    Stack更新
                    (ENV, EXIT_CODE)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| repl.rs | `crates/nu-cli/src/repl.rs` | ソース | REPLのメイン実装 |
| completer.rs | `crates/nu-cli/src/completions/completer.rs` | ソース | 補完機能のコア実装 |
| nu_highlight.rs | `crates/nu-cli/src/nu_highlight.rs` | ソース | シンタックスハイライト |
| prompt.rs | `crates/nu-cli/src/prompt.rs` | ソース | プロンプト表示 |
| prompt_update.rs | `crates/nu-cli/src/prompt_update.rs` | ソース | プロンプト更新処理 |
| reedline_config.rs | `crates/nu-cli/src/reedline_config.rs` | ソース | reedline設定 |
| validation.rs | `crates/nu-cli/src/validation.rs` | ソース | 入力バリデーション |
| engine_state.rs | `crates/nu-protocol/src/engine/engine_state.rs` | ソース | エンジン状態管理 |
| stack.rs | `crates/nu-protocol/src/engine/stack.rs` | ソース | スタック管理 |
| config.nu | `$nu.default-config-dir/config.nu` | 設定 | ユーザー設定ファイル |
