# 機能設計書 68-ls色設定

## 概要

本ドキュメントは、Oh My Zshのテーマ・外観機能における`ls`コマンドのカラー設定の設計を記載する。この機能は、プラットフォームに応じた適切な`LSCOLORS`/`LS_COLORS`環境変数を設定し、カラー表示を有効にした`ls`エイリアスを定義する。

### 本機能の処理概要

**業務上の目的・背景**：ディレクトリ一覧を表示する際、ファイルの種類（ディレクトリ、実行ファイル、シンボリックリンク等）を色で区別できると、ファイルの識別が容易になる。この機能は、macOS（BSD ls）とLinux（GNU ls）の両方で統一されたカラー表示を実現し、ユーザー体験を向上させる。

**機能の利用シーン**：
- ディレクトリ内のファイル一覧を確認する際
- ファイルの種類を視覚的に識別したい場合
- シンボリックリンクや実行ファイルを素早く見つけたい場合

**主要な処理内容**：
1. `DISABLE_LS_COLORS`が設定されている場合は処理をスキップする
2. BSD系ls用の`LSCOLORS`環境変数を設定する
3. GNU系ls用の`LS_COLORS`環境変数を設定する（dircolorsコマンドが利用可能な場合はそれを使用）
4. プラットフォームに応じた適切な`ls`エイリアスを定義する

**関連システム・外部連携**：
- BSD ls（macOS、FreeBSD等）
- GNU ls（Linux、GNU coreutils）
- dircolorsコマンド（GNU coreutils）
- gls（GNU lsの別名、macOSでcoreutils経由でインストール）
- colorls（OpenBSDのカラー対応ls）

**権限による制御**：`DISABLE_LS_COLORS`環境変数がtrueの場合、この機能は無効化される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | CLIコマンドのため関連画面なし |

## 機能種別

環境設定 / エイリアス定義

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | 初期化処理のため入力パラメータなし | - |

### 入力データソース

- 環境変数: `$DISABLE_LS_COLORS`, `$OSTYPE`, `$LS_COLORS`
- ファイル: `$HOME/.dircolors`（存在する場合）
- コマンド: `dircolors`, `gls`, `colorls`, `ls`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| LSCOLORS | string | BSD ls用の色設定環境変数 |
| LS_COLORS | string | GNU ls用の色設定環境変数 |
| lsエイリアス | alias | カラー有効のlsエイリアス |

### 出力先

- 環境変数（export）
- シェルエイリアス

## 処理フロー

### 処理シーケンス

```
1. DISABLE_LS_COLORSチェック
   └─ trueなら即座にreturn
2. LSCOLORS設定（BSD用）
   └─ export LSCOLORS="Gxfxcxdxbxegedabagacad"
3. LS_COLORS設定（GNU用）
   ├─ LS_COLORSが未設定の場合
   │   ├─ dircolorsが利用可能
   │   │   ├─ ~/.dircolorsが存在 → source <(dircolors -b ~/.dircolors)
   │   │   └─ 存在しない → source <(dircolors -b)
   │   └─ dircolors利用不可 → デフォルトLS_COLORSを設定
   └─ 既に設定済みならスキップ
4. test-ls-args関数定義
   └─ lsコマンドのオプションサポートを確認する補助関数
5. プラットフォーム別lsエイリアス定義
   ├─ NetBSD: glsが利用可能なら gls --color
   ├─ OpenBSD: colorlsまたはgls
   ├─ macOS/FreeBSD: ls -G または zstyle設定時はgls --color
   └─ その他: ls --color または ls -G
6. test-ls-args関数削除
```

### フローチャート

```mermaid
flowchart TD
    A[theme-and-appearance.zsh読み込み] --> B{DISABLE_LS_COLORS == true?}
    B -->|Yes| C[return 0 - 処理終了]
    B -->|No| D[LSCOLORS設定]
    D --> E{LS_COLORS設定済み?}
    E -->|Yes| G[スキップ]
    E -->|No| F{dircolors利用可能?}
    F -->|Yes| H{~/.dircolors存在?}
    H -->|Yes| I[dircolors -b ~/.dircolors]
    H -->|No| J[dircolors -b デフォルト]
    F -->|No| K[デフォルトLS_COLORS設定]
    G --> L[test-ls-args関数定義]
    I --> L
    J --> L
    K --> L
    L --> M{$OSTYPE判定}
    M -->|netbsd| N[gls --color]
    M -->|openbsd| O[colorls -G または gls --color]
    M -->|darwin/freebsd| P[ls -G または zstyle時gls]
    M -->|その他| Q[ls --color または ls -G]
    N --> R[unfunction test-ls-args]
    O --> R
    P --> R
    Q --> R
    R --> S[終了]
    C --> S
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 無効化オプション | DISABLE_LS_COLORSがtrueの場合、カラー設定をスキップ | 環境変数設定時 |
| BR-02 | LS_COLORS優先 | 既存のLS_COLORS設定を上書きしない | LS_COLORSが設定済みの場合 |
| BR-03 | dircolors優先 | dircolorsが利用可能ならそれを使用してLS_COLORSを設定 | dircolorsコマンド存在時 |
| BR-04 | ユーザー設定優先 | ~/.dircolorsが存在する場合はそれを使用 | ファイル存在時 |
| BR-05 | zstyle設定 | `:omz:lib:theme-and-appearance` gnu-ls設定でGNU lsを優先 | macOS/FreeBSDでzstyle設定時 |

### 計算ロジック

**LSCOLORSの色設定**:
```
LSCOLORS="Gxfxcxdxbxegedabagacad"
```
各2文字が1つのファイルタイプの前景色・背景色を表す:
- G: ディレクトリ（シアン太字）
- x: シンボリックリンク（デフォルト）
- f: ソケット（マゼンタ）
- c: パイプ（黄色）
- d: 実行ファイル（赤）
- b: ブロックデバイス（青+シアン背景）
- e: キャラクタデバイス（青+黄色背景）
- a: SUIDファイル（黒+赤背景）
- g: SGIDファイル（黒+シアン背景）
- a: スティッキービット+other writable（黒+緑背景）
- c: other writable（黒+黄色背景）
- a: リンク切れシンボリックリンク（黒+赤背景）
- d: 存在しないファイルへのリンク（赤）

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

該当なし（データベースを使用しない）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | オプション非対応 | ls -G や ls --color が使えない古いシステム | エイリアスを定義しない |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- シェル起動時に1回のみ実行されるため、数十ミリ秒で完了すれば十分
- dircolorsの実行は軽量

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

- ~/.dircolorsファイルはユーザーが編集可能だが、source実行されるため信頼できる内容である必要がある

## 備考

- LSCOLORSはBSD系、LS_COLORSはGNU系で使用される
- geoff.greer.fm/lscolorsでLSCOLORSとLS_COLORSの相互変換が可能
- colorlsはOpenBSDのベースシステムに含まれるカラー対応ls

---

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

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

### 推奨読解順序

#### Step 1: 無効化チェックとLSCOLORS設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | theme-and-appearance.zsh | `lib/theme-and-appearance.zsh` | 23-27行目のチェックとLSCOLORS設定 |

**主要処理フロー**:
- **24行目**: `[[ "$DISABLE_LS_COLORS" != true ]] || return 0` - 無効化チェック
- **27行目**: `export LSCOLORS="Gxfxcxdxbxegedabagacad"` - BSD ls用色設定

**読解のコツ**:
- `[[ ... ]] || return 0`は条件が偽の場合にreturnする（trueなら早期終了）
- LSCOLORSは2文字ずつで1つのファイルタイプの色を表す

#### Step 2: LS_COLORS設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | theme-and-appearance.zsh | `lib/theme-and-appearance.zsh` | 29-40行目のLS_COLORS設定 |

**主要処理フロー**:
- **30行目**: `if [[ -z "$LS_COLORS" ]]; then` - LS_COLORSが未設定かチェック
- **33行目**: `if (( $+commands[dircolors] )); then` - dircolorsコマンド存在確認
- **34-36行目**: ~/.dircolorsの有無でdircolors実行方法を切り替え
- **38行目**: dircolors非対応時のデフォルトLS_COLORS

**読解のコツ**:
- `$+commands[cmd]`はコマンドの存在確認（存在すれば1）
- `source <(command)`はプロセス置換でコマンド出力をsource

#### Step 3: test-ls-args関数とプラットフォーム別処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | theme-and-appearance.zsh | `lib/theme-and-appearance.zsh` | 42-81行目のlsエイリアス設定 |

**主要処理フロー**:
- **42-46行目**: `function test-ls-args` - lsオプションのサポート確認関数
- **49-82行目**: case文でプラットフォーム別処理
  - **50-53行目**: NetBSD - glsがあれば使用
  - **55-62行目**: OpenBSD - colorlsまたはgls
  - **63-71行目**: macOS/FreeBSD - ls -G、zstyle設定時はgls
  - **72-78行目**: その他 - ls --color または ls -G
- **81行目**: `unfunction test-ls-args` - 一時関数の削除

**読解のコツ**:
- `test-ls-args gls --color`は`gls --color /dev/null`を実行してエラーを確認
- `zstyle -t ':omz:lib:theme-and-appearance' gnu-ls`はzstyle設定の確認

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

```
theme-and-appearance.zsh source
    │
    ├─ DISABLE_LS_COLORS チェック
    │      └─ true → return
    │
    ├─ LSCOLORS設定（BSD用）
    │
    ├─ LS_COLORS設定（GNU用）
    │      ├─ dircolors利用可能
    │      │      └─ ~/.dircolors または デフォルト
    │      └─ dircolors利用不可
    │             └─ デフォルトLS_COLORS
    │
    ├─ test-ls-args関数定義
    │
    ├─ プラットフォーム別lsエイリアス
    │      ├─ NetBSD → gls --color
    │      ├─ OpenBSD → colorls -G または gls --color
    │      ├─ macOS/FreeBSD → ls -G または gls --color
    │      └─ その他 → ls --color または ls -G
    │
    └─ test-ls-args関数削除
```

### データフロー図

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

$DISABLE_LS_COLORS ────────────▶ 有効/無効判定

                                                                ┌─ LSCOLORS (BSD)
~/.dircolors ──────────────────▶ dircolors -b ─────────────────▶│   環境変数
                                                                └─ LS_COLORS (GNU)
$OSTYPE ───────────────────────▶                                    環境変数
                                  プラットフォーム判定
$commands[gls] ────────────────▶                               ┌─ alias ls='ls -G'
$commands[colorls] ────────────▶  lsエイリアス決定 ───────────▶├─ alias ls='ls --color=tty'
                                                                └─ alias ls='gls --color=tty'
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| theme-and-appearance.zsh | `lib/theme-and-appearance.zsh` | ソース | ls色設定およびテーマ・外観設定のメイン実装 |
| .dircolors | `~/.dircolors` | 設定（オプション） | ユーザーカスタム色設定 |
