# 画面設計書 4-レコードビュー

## 概要

本ドキュメントは、Nushell Exploreにおけるレコードビュー画面の設計仕様を定義する。レコードビューは、テーブルやレコードデータをインタラクティブに表示・ナビゲートするためのTUI画面である。

### 本画面の処理概要

レコードビューは、`explore`コマンドによって表示されるデータ探索画面の中核となるビューである。テーブル形式のデータをグリッド表示し、カーソル操作によるナビゲーション、ドリルダウン、転置などの操作を提供する。

**業務上の目的・背景**：
Nushellは構造化データ（テーブル、レコード、リスト）をネイティブにサポートしており、これらのデータを効率的に閲覧・分析する手段が必要である。レコードビューは、大量のデータをページング表示し、ネストしたデータ構造をドリルダウンで探索できるインタラクティブなUIを提供する。VIEWモードとCURSORモードの2つの操作モードにより、データの閲覧と選択を直感的に切り替えられる。

**画面へのアクセス方法**：
- メインREPLで `explore` コマンドを実行
- パイプラインの出力を `| explore` で受け取る
- 例: `ls | explore`, `$env | explore`

**主要な操作・処理内容**：
1. テーブル/レコードデータのグリッド表示
2. VIEWモードでのスクロール（矢印キー、Page Up/Down）
3. CURSORモードでのセル選択とドリルダウン（Enter）
4. 転置操作（t キー）で行列を入れ替え
5. 展開操作（e キー）でネストデータをプレビュー
6. コマンド入力（:try, :nu, :help, :q）

**画面遷移**：
- メインREPL（画面No.1） → explore コマンド → レコードビュー
- レコードビュー → :try → Tryビュー（画面No.7）
- レコードビュー → :nu cmd → Nuコマンドビュー（画面No.8）
- レコードビュー → :help → ヘルプ画面（画面No.9）
- レコードビュー → e キー → プレビュー（画面No.6）
- レコードビュー → :q / Esc → メインREPL（画面No.1）

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 69 | テーブル表示 | 主機能 | テーブル・レコードデータのインタラクティブ表示 |
| 71 | 探索モード | 主機能 | VIEWモードとCURSORモードによるデータナビゲーション |
| 17 | 変形・整形 | 補助機能 | transpose操作によるテーブルの行列変換 |
| 16 | 選択・抽出 | 補助機能 | カーソル位置の値の選択・ドリルダウン |

## 画面種別

TUI（Terminal User Interface）データビューア

## URL/ルーティング

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

## 入出力項目

| 項目名 | 型 | 入力/出力 | 説明 |
|--------|-----|----------|------|
| 入力データ | Value | 入力 | 表示対象のテーブル/レコード/リストデータ |
| カラム名 | Vec<String> | 入力/処理 | テーブルのカラム名一覧 |
| レコード値 | Vec<Vec<Value>> | 入力/処理 | テーブルの各行のデータ |
| 選択値 | Value | 出力 | CURSORモードで選択された値 |
| 終了時の値 | Value | 出力 | ビュー終了時に返す値 |

## 表示項目

| 項目名 | 説明 | 表示形式 |
|--------|------|----------|
| ヘッダー行 | カラム名を表示 | テーブルヘッダー |
| データ行 | 各レコードの値 | テーブル行 |
| ステータスバー | モード、カーソル位置、スクロール位置 | 下部バー |
| 選択ハイライト | CURSORモードでの選択セル | 反転表示 |
| レイヤー名 | ドリルダウン時の列名 | ステータスに表示 |

## イベント仕様

### 1-Enter押下（モード切替/ドリルダウン）

**VIEWモードの場合：**
1. CURSORモードに切り替え
2. カーソルを現在位置で表示

**CURSORモードの場合：**
1. 現在のセル値を取得
2. 値がRecord/List/Customの場合のみドリルダウン
3. 新しいRecordLayerを作成してスタックに追加
4. 子データを新しいビューで表示

### 2-Esc押下（戻る/モード切替）

**VIEWモードの場合：**
- レイヤースタックが1より大きければ: 上のレイヤーに戻る
- レイヤースタックが1の場合: Exploreを終了

**CURSORモードの場合：**
1. VIEWモードに切り替え

### 3-矢印キー（ナビゲーション）

**VIEWモードの場合：**
- ウィンドウ全体をスクロール（prev_row_i, next_row_i等）

**CURSORモードの場合：**
- カーソルを1セル移動（prev_row, next_row等）

### 4-Page Up/Page Down（ページ移動）

1. ページサイズを計算（表示可能行数）
2. ウィンドウ開始位置を更新
3. ステータスバーを更新

### 5-t キー（転置）

**VIEWモードの場合のみ有効：**
1. transpose_table関数を呼び出し
2. 行と列を入れ替え
3. カーソル位置をリセット

### 6-e キー（展開）

1. Transition::Cmd("expand")を返却
2. 上位でexpandコマンドが処理されプレビュー表示

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

N/A（データベース操作なし）

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 発生条件 |
|-------------|------|---------------|----------|
| TOP | 情報 | Top | スクロール位置が先頭 |
| ALL | 情報 | All | 全データが表示されている |
| PERCENT | 情報 | X% | スクロール位置のパーセント |
| MODE_VIEW | 情報 | VIEW | VIEWモード時 |
| MODE_EDIT | 情報 | EDIT | CURSORモード時 |
| EMPTY_COLLECTION | エラー | Nothing to explore in empty collections! | 空のコレクションを表示しようとした場合 |

## 例外処理

| 例外状態 | 対応処理 |
|---------|---------|
| 空のコレクション | エラーメッセージを返却、create_layerがErr |
| ドリルダウン不可値 | Transition::Noneを返却、何も起こらない |
| カーソル範囲外 | assert!でパニック（通常は発生しない） |

## 備考

- RecordLayerスタックによるドリルダウン履歴管理
- Orientationで縦横表示を切り替え可能（Top/Left）
- auto_tailモードで新規行を自動追従
- lscolorizeによるファイル名の色付け対応
- セル内容の省略表示（to_abbreviated_string）

---

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

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

### 推奨読解順序

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

レコードビューで扱う主要なデータ構造を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | RecordView構造体（29-37行） |
| 1-2 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | RecordLayer構造体（417-433行） |
| 1-3 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | UIMode列挙型（411-415行） |

**読解のコツ**: RecordViewはRecordLayerのスタックを持ち、ドリルダウンで新しいレイヤーが追加される

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

Viewトレイト実装を通じて画面描画と入力処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | View for RecordView実装（188-346行） |

**主要処理フロー**:
1. **189-233行**: `draw`関数 - テーブルウィジェットの描画
2. **235-285行**: `handle_input`関数 - キー入力処理
3. **343-345行**: `exit`関数 - 終了時の値返却

#### Step 3: カーソル操作を理解する

CursorMoveHandlerトレイト実装を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | CursorMoveHandler実装（484-570行） |

**主要処理フロー**:
- **488-515行**: `handle_enter` - Enter押下時の処理
- **516-529行**: `handle_esc` - Esc押下時の処理
- **530-532行**: `handle_expand` - 展開処理
- **533-542行**: `handle_transpose` - 転置処理
- **546-569行**: `handle_left/right/up/down` - カーソル移動

#### Step 4: レイヤー管理を理解する

ドリルダウンとレイヤースタックの管理を追う。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | create_layer関数（572-578行） |
| 4-2 | mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | push_layer関数（580-591行） |

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

```
explore コマンド
    |
    +-- RecordView::new()                [mod.rs:40]
            |
            +-- RecordLayer::new()       [mod.rs:436]
                    |
                    +-- WindowCursor2D::new()

RecordView::draw()                       [mod.rs:189]
    |
    +-- create_table_widget()            [mod.rs:127]
    |       +-- convert_records_to_string()  [mod.rs:615]
    |       +-- lscolorize()
    |
    +-- TableWidget::new()
    +-- f.render_stateful_widget()

RecordView::handle_input()               [mod.rs:235]
    |
    +-- handle_input_key()               [CursorMoveHandler]
            |
            +-- handle_enter()           [mod.rs:488]
            |       +-- set_cursor_mode()
            |       +-- get_current_value()
            |       +-- create_layer()
            |       +-- push_layer()
            |
            +-- handle_esc()             [mod.rs:516]
            |       +-- layer_stack.pop()
            |       +-- set_view_mode()
            |
            +-- handle_transpose()       [mod.rs:533]
                    +-- transpose_table()  [mod.rs:672]
```

### データフロー図

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

Value（テーブル） ────────▶ collect_input()
                            │
                            ▼
                      RecordLayer::new()
                            │
                            ▼
columns, values ─────────▶ RecordView
                            │
                            ▼
                      draw()
                            │
                            ▼
                      TableWidget ───────────────────▶ TUI画面描画
                            │
                      handle_input()
                            │
     ┌──────────────────────┼──────────────────────┐
     │                      │                      │
     ▼                      ▼                      ▼
Enter押下              矢印キー押下           Esc押下
(ドリルダウン)         (カーソル移動)         (戻る)
     │                      │                      │
     ▼                      ▼                      ▼
push_layer()          cursor更新            layer_stack.pop()
                                            or
                                            exit() ──────▶ 選択値を返却
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| mod.rs | `crates/nu-explore/src/explore/views/record/mod.rs` | ソース | レコードビューのコア実装 |
| table_widget.rs | `crates/nu-explore/src/explore/views/record/table_widget.rs` | ソース | テーブル描画ウィジェット |
| cursor/mod.rs | `crates/nu-explore/src/explore/views/cursor/mod.rs` | ソース | カーソル管理モジュール |
| window_cursor_2d.rs | `crates/nu-explore/src/explore/views/cursor/window_cursor_2d.rs` | ソース | 2Dカーソル実装 |
| util.rs | `crates/nu-explore/src/explore/views/util.rs` | ソース | ユーティリティ関数 |
| config.rs | `crates/nu-explore/src/explore/config.rs` | ソース | Explore設定 |
| pager/mod.rs | `crates/nu-explore/src/explore/pager/mod.rs` | ソース | ページャーのコア |
| status_bar.rs | `crates/nu-explore/src/explore/pager/status_bar.rs` | ソース | ステータスバー |
| value.rs | `crates/nu-explore/src/explore/nu_common/value.rs` | ソース | Value処理 |
| lscolor.rs | `crates/nu-explore/src/explore/nu_common/lscolor.rs` | ソース | ls色付け |
