# 機能設計書 26-ANSI制御

## 概要

本ドキュメントは、NushellにおけるANSI制御機能の設計仕様を記述する。

### 本機能の処理概要

ANSI制御機能は、ターミナルの表示を制御するANSIエスケープシーケンスの生成・除去・操作機能を提供する。テキストの色付け、スタイル設定、ハイパーリンクの挿入など、ターミナル出力の見た目をカスタマイズするために使用される。

**業務上の目的・背景**：ターミナルベースのツールにおいて、視覚的なフィードバックは重要な役割を果たす。エラーメッセージの赤色表示、成功メッセージの緑色表示、重要な情報の太字表示など、ANSIエスケープシーケンスによる色付けとスタイル設定により、ユーザーが情報を素早く認識できるようになる。

**機能の利用シーン**：
- スクリプト出力に色付けして見やすくする場合
- エラーや警告を視覚的に強調する場合
- ターミナルにハイパーリンクを挿入する場合
- 外部プログラムの出力からANSIコードを除去する場合

**主要な処理内容**：
1. `ansi` - ANSIエスケープコードの生成
2. `ansi strip` - 文字列からANSIエスケープシーケンスを除去
3. `ansi link` - OSC 8形式のハイパーリンクを挿入
4. `ansi gradient` - グラデーション効果の適用（nu-cmd-extra）

**関連システム・外部連携**：ターミナルエミュレータとの連携。ANSIエスケープシーケンスをサポートするターミナルで動作する。

**権限による制御**：特になし。すべてのユーザーが使用可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | メインREPL | 主機能 | 色付き出力、プロンプトの装飾 |

## 機能種別

出力装飾 / ターミナル制御

## 入力仕様

### 入力パラメータ

#### ansi

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| code | String | Yes | ANSIコード名（例: "green", "bold"） | 有効なコード名 |
| --escape / -e | Switch | No | エスケープ文字を`\e[`形式で出力 | - |
| --osc / -o | Switch | No | OSCエスケープシーケンス | - |

#### ansi strip

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| rest | CellPath | No | データ構造内の対象セルパス | - |

#### ansi link

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| --text / -t | String | No | リンクテキスト（省略時はURI） | - |
| rest | CellPath | No | データ構造内の対象セルパス | - |

### 入力データソース

パイプライン入力（文字列、リスト、テーブル、レコード）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| result (ansi) | String | ANSIエスケープシーケンス |
| result (ansi strip) | String | ANSIコード除去後の文字列 |
| result (ansi link) | String | OSC 8形式リンク付き文字列 |

### 出力先

パイプライン出力

## 処理フロー

### 処理シーケンス

```
1. コマンド引数を解析する
   └─ コード名、オプションフラグを取得
2. ANSIエスケープシーケンスの処理
   └─ ansi: コード名からエスケープシーケンスを生成
   └─ ansi strip: 文字列からANSIコードを除去
   └─ ansi link: OSC 8形式のリンクを構築
3. 結果を出力する
```

### フローチャート

```mermaid
flowchart TD
    A[入力受信] --> B{コマンド種別}
    B -->|ansi| C[コード名解析]
    B -->|ansi strip| D[ANSIコード除去]
    B -->|ansi link| E[リンク構築]
    C --> F{コード名検索}
    F -->|found| G[エスケープシーケンス出力]
    F -->|not found| H[エラー出力]
    D --> I[nu_utils::strip_ansi_likely]
    I --> J[クリーン文字列出力]
    E --> K[OSC 8形式構築]
    K --> L[リンク付き文字列出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-26-1 | コード名検索 | 短縮名と長名の両方で検索可能 | ansi使用時 |
| BR-26-2 | 16/256色サポート | 標準16色とXterm 256色をサポート | ansi使用時 |
| BR-26-3 | OSC 8形式 | ハイパーリンクはOSC 8エスケープシーケンスを使用 | ansi link使用時 |
| BR-26-4 | strip処理 | nu_utilsのstrip_ansi_likely関数を使用 | ansi strip使用時 |

### 計算ロジック

ANSIエスケープシーケンスの形式：
- 色: `\x1b[{code}m`（例: `\x1b[32m` = 緑色）
- リセット: `\x1b[0m`
- OSC 8リンク: `\x1b]8;;{url}\x1b\\{text}\x1b]8;;\x1b\\`

サポートされる色コード例：
- g, green: 緑色
- r, red: 赤色
- b, blue: 青色
- gb, green_bold: 緑色太字
- reset: リセット

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| UnknownCommand | 不明コード | 無効なANSIコード名 | 有効なコード名を使用 |
| TypeMismatch | 型エラー | 文字列以外をansi linkに渡した場合 | 文字列を入力する |

### リトライ仕様

該当なし

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

該当なし（ステートレス処理）

## パフォーマンス要件

- nu_ansi_termクレートによる効率的なANSIコード生成
- 静的なコードリストによる高速な検索

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

- ANSIエスケープシーケンスはターミナルエミュレータの脆弱性を悪用される可能性
- 外部入力を直接表示する場合はansi stripでサニタイズを推奨

## 備考

- nu_ansi_termクレートによるANSI色処理
- 256色モード（Xterm）の完全サポート
- カスタムRGB色も指定可能

---

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

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

### 推奨読解順序

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

ANSIコードの定義構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ansi_.rs | `crates/nu-command/src/strings/ansi/ansi_.rs` | AnsiCode構造体（10-14行目）- コード定義 |
| 1-2 | ansi_.rs | `crates/nu-command/src/strings/ansi/ansi_.rs` | CODE_LIST（17-300行目）- 全コードリスト |

**読解のコツ**: CODE_LISTはLazyLockで遅延初期化される静的なANSIコードリスト。短縮名（short_name）と長名（long_name）の両方でアクセス可能。

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

コマンド実行の起点を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | strip.rs | `crates/nu-command/src/strings/ansi/strip.rs` | `impl Command for AnsiStrip`（21-86行目） |
| 2-2 | link.rs | `crates/nu-command/src/strings/ansi/link.rs` | `impl Command for AnsiLink`（6-77行目） |

**主要処理フロー**:
1. **strip.rs 47-59行目**: `run`メソッドでoperate呼び出し
2. **link.rs 42-50行目**: `run`メソッドでoperate呼び出し

#### Step 3: 処理ロジックを理解する

実際のANSI処理を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | strip.rs | `crates/nu-command/src/strings/ansi/strip.rs` | action関数（88-100行目）- strip処理 |
| 3-2 | link.rs | `crates/nu-command/src/strings/ansi/link.rs` | add_osc_link関数（141-143行目）- リンク構築 |

**主要処理フロー**:
- **strip.rs 92行目**: nu_utils::strip_ansi_likelyでANSI除去
- **link.rs 142行目**: OSC 8形式のエスケープシーケンス構築

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

```
Ansi::run
    │
    ├─ call.req("code") - コード名取得
    │
    └─ CODE_MAP / CODE_LIST から検索
           │
           └─ AnsiCode.code を出力

AnsiStrip::run
    │
    ├─ call.rest() - セルパス取得
    │
    └─ operate()
           │
           └─ action()
                  │
                  └─ nu_utils::strip_ansi_likely()

AnsiLink::run
    │
    ├─ call.get_flag("text") - テキスト取得
    │
    └─ operate()
           │
           └─ process_value()
                  │
                  └─ add_osc_link()
                         │
                         └─ \x1b]8;;{url}\x1b\\{text}\x1b]8;;\x1b\\
```

### データフロー図

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

"green" ───▶ ansi ───▶ CODE_MAP検索 ───▶ "\x1b[32m"

String ───▶ ansi strip ───▶ strip_ansi_likely ───▶ CleanString
   │
   └─ "\x1b[32mhello\x1b[0m" → "hello"

URL ───▶ ansi link ───▶ add_osc_link ───▶ OSC 8 String
   │
   └─ "https://example.com" + "Click" → "\x1b]8;;https://example.com\x1b\\Click\x1b]8;;\x1b\\"
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| ansi_.rs | `crates/nu-command/src/strings/ansi/ansi_.rs` | ソース | ansi コマンド実装、コードリスト |
| strip.rs | `crates/nu-command/src/strings/ansi/strip.rs` | ソース | ansi strip コマンド実装 |
| link.rs | `crates/nu-command/src/strings/ansi/link.rs` | ソース | ansi link コマンド実装 |
| mod.rs | `crates/nu-command/src/strings/ansi/mod.rs` | ソース | ansiモジュール定義 |
| gradient.rs | `crates/nu-cmd-extra/src/extra/platform/ansi/gradient.rs` | ソース | ansi gradient コマンド（extra） |
