# 機能設計書 13-omz theme list

## 概要

本ドキュメントは、Oh My Zshの`omz theme list`コマンドの機能設計について記載する。このコマンドはOh My Zshで利用可能なテーマ一覧を表示する機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：Oh My Zshには150以上のビルトインテーマが存在し、さらにユーザーがカスタムテーマを作成することも可能である。ユーザーがプロンプトの外観をカスタマイズする際に、利用可能なテーマを把握し、適切なテーマを選択するために、テーマ一覧を確認する機能が必要となる。本機能は、ビルトインテーマとカスタムテーマの両方を一覧表示し、現在使用中のテーマも表示することで、ユーザーのテーマ選択を支援する。

**機能の利用シーン**：
- 利用可能なテーマを探索したい場合
- 現在使用中のテーマを確認したい場合
- テーマ変更（`omz theme set`や`omz theme use`）前にテーマ名を確認する場合
- シェルスクリプト等でテーマ一覧を取得してパイプ処理する場合

**主要な処理内容**：
1. `$ZSH_CUSTOM`配下からカスタムテーマ（`*.zsh-theme`）を収集する
2. `$ZSH/themes`ディレクトリからビルトインテーマを収集する
3. 標準出力がTTYかパイプかを判定し、出力形式を決定する
4. TTYの場合は現在のテーマ、カスタムテーマ、ビルトインテーマの順に表示
5. パイプの場合は1行1テーマで出力する

**関連システム・外部連携**：特になし。ローカルファイルシステムのみを参照する。

**権限による制御**：特になし。テーマディレクトリへの読み取り権限があれば実行可能。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | omz theme list | 主画面 | 利用可能なテーマ一覧を表示 |

## 機能種別

データ参照・一覧表示

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| - | - | - | パラメータなし | - |

### 入力データソース

- `$ZSH_CUSTOM/**/*.zsh-theme`: カスタムテーマファイル（サブディレクトリ含む）
- `$ZSH/themes/*.zsh-theme`: ビルトインテーマファイル
- `$ZSH_THEME`: 現在設定されているテーマ名
- `$RANDOM_THEME`: ランダムテーマ使用時の実際のテーマ名

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| current_theme | 文字列 | 現在使用中のテーマ名（TTY出力時のみ） |
| custom_themes | 配列 | カスタムテーマ名の一覧 |
| builtin_themes | 配列 | ビルトインテーマ名の一覧 |

### 出力先

- 標準出力（ターミナル）: カテゴリ別にフォーマットされた表示
- 標準出力（パイプ）: 1行1テーマ形式での出力

### 出力形式

**TTY出力時**:
```
Current theme: robbyrussell

Custom themes:
mytheme  mytheme2

Built-in themes:
robbyrussell  agnoster  amuse  ...
```

**パイプ出力時**:
```
mytheme
mytheme2
robbyrussell
agnoster
...
```

## 処理フロー

### 処理シーケンス

```
1. テーマ収集
   ├─ $ZSH_CUSTOM/**/*.zsh-themeからカスタムテーマを取得
   │   └─ パス正規化（$ZSH_CUSTOM/themes/と$ZSH_CUSTOM/を削除）
   └─ $ZSH/themes/*.zsh-themeからビルトインテーマを取得
       └─ 拡張子とディレクトリパスを削除

2. 出力先判定
   └─ [ ! -t 1 ] でTTYかパイプかを判定

3. パイプ出力
   └─ print -l で1行1テーマ出力

4. TTY出力
   ├─ 現在のテーマを表示（$ZSH_THEMEが設定されている場合）
   │   └─ randomテーマの場合は実際のテーマ名も表示
   ├─ カスタムテーマを表示（存在する場合）
   └─ ビルトインテーマを表示
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[カスタムテーマを収集]
    B --> C[ビルトインテーマを収集]
    C --> D{出力先はTTY?}
    D -->|No| E[1行1テーマで出力]
    E --> F[終了]
    D -->|Yes| G{$ZSH_THEMEが設定されている?}
    G -->|Yes| H[Current theme:を表示]
    H --> I{$ZSH_THEME = random?}
    I -->|Yes| J[$RANDOM_THEME (via random)を表示]
    I -->|No| K[$ZSH_THEMEを表示]
    J --> L{カスタムテーマあり?}
    K --> L
    G -->|No| L
    L -->|Yes| M[Custom themes:ヘッダー出力]
    M --> N[カスタムテーマをカラム出力]
    N --> O[Built-in themes:ヘッダー出力]
    L -->|No| O
    O --> P[ビルトインテーマをカラム出力]
    P --> F
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | テーマファイル拡張子 | `.zsh-theme`拡張子を持つファイルをテーマとして認識 | 常時 |
| BR-02 | カスタムテーマパス正規化 | `$ZSH_CUSTOM/themes/`と`$ZSH_CUSTOM/`のプレフィックスを削除してテーマ名を抽出 | カスタムテーマ処理時 |
| BR-03 | 現在のテーマ表示 | TTY出力時、`$ZSH_THEME`が設定されていれば先頭に表示 | TTY出力時 |
| BR-04 | ランダムテーマ表示 | `$ZSH_THEME`が`random`の場合、実際のテーマ名（`$RANDOM_THEME`）も併せて表示 | $ZSH_THEME=random時 |
| BR-05 | 出力形式切り替え | パイプ処理時は機械可読形式（1行1テーマ）で出力 | stdout が非TTYの場合 |

### 計算ロジック

特になし。

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

本機能ではデータベース操作は行わない。ファイルシステムのみを参照する。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | ディレクトリ不在 | テーマディレクトリが存在しない | 空の配列として処理（エラーにならない） |

### リトライ仕様

リトライは行わない。

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

該当なし（データベース操作なし）。

## パフォーマンス要件

- 通常の環境では1秒以内に応答すること
- ディレクトリ走査にはzshのglob機能を使用し、高速に処理する

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

- テーマディレクトリの読み取り権限のみを使用
- テーマファイルの内容は読み取らず、ファイル名のみを取得
- 出力時にシェルエスケープ（`${(q-)}`）を行い、特殊文字を含むテーマ名も安全に表示

## 備考

- `print -lac`オプションにより、ターミナル幅に応じて自動的にカラム数が調整される
- カスタムテーマは`$ZSH_CUSTOM`直下、`$ZSH_CUSTOM/themes/`、またはサブディレクトリに配置可能
- glob展開`**/*.zsh-theme`によりサブディレクトリ内のテーマも検出される

---

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

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

### 推奨読解順序

#### Step 1: 関数の全体構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cli.zsh | `lib/cli.zsh` | `_omz::theme::list`関数の定義位置（766-794行目）を確認 |

**読解のコツ**: zshの文字列置換記法`:gs:A:B:`は、文字列A をBに置換する。空文字列への置換でパス部分を削除している。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | cli.zsh | `lib/cli.zsh` | omz関数（3-21行目）からのコマンドディスパッチを確認 |
| 2-2 | cli.zsh | `lib/cli.zsh` | _omz::theme関数（745-764行目）からのサブコマンドディスパッチを確認 |

**主要処理フロー**:
1. **3-21行目**: `omz`関数がコマンドライン引数を解析し、`_omz::$command`を呼び出す
2. **745-764行目**: `_omz::theme`関数が`list`サブコマンドを受け取り、`_omz::theme::list`を呼び出す

#### Step 3: テーマ一覧取得処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cli.zsh | `lib/cli.zsh` | `_omz::theme::list`関数（766-794行目）の実装詳細 |

**主要処理フロー**:
- **767-769行目**: ローカル変数の宣言とテーマ収集
- **768行目**: カスタムテーマの収集（glob展開とパス正規化）
- **769行目**: ビルトインテーマの収集
- **771-774行目**: パイプ出力時の処理（`print -l`で1行1テーマ）
- **777-781行目**: 現在のテーマを表示
- **784-788行目**: カスタムテーマの表示
- **791-793行目**: ビルトインテーマの表示

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

```
omz (3-21行目)
    │
    └─ _omz::theme (745-764行目)
           │
           └─ _omz::theme::list (766-794行目)
                  │
                  ├─ カスタムテーマ収集 (glob展開)
                  │
                  └─ ビルトインテーマ収集 (glob展開)
```

### データフロー図

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

$ZSH_CUSTOM/**/*.zsh-theme ───▶ パス正規化              ───▶ custom_themes配列
                                    │
$ZSH/themes/*.zsh-theme    ───▶ 拡張子・パス削除       ───▶ builtin_themes配列
                                    │
                                    ▼
$ZSH_THEME, $RANDOM_THEME  ───▶ 出力先判定
                                    │
                                    ├─ TTY: カテゴリ別表示
                                    └─ パイプ: 1行1テーマ
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| cli.zsh | `lib/cli.zsh` | ソース | omzコマンドのCLI実装。_omz::theme::list関数を含む |
| oh-my-zsh.sh | `oh-my-zsh.sh` | ソース | $ZSH_THEMEと$RANDOM_THEMEの設定を行うメインスクリプト |
