# 機能設計書 62-title

## 概要

本ドキュメントは、Oh My Zshのターミナルサポート機能における`title`関数の設計を記載する。この関数は、ターミナルエミュレータのウィンドウタイトルとタブタイトルを設定するための統一インターフェースを提供する。

### 本機能の処理概要

**業務上の目的・背景**：ターミナルを複数のタブやウィンドウで使用する場合、各ターミナルの用途を視覚的に識別できることが重要である。この機能は、異なるターミナルエミュレータ（xterm、iTerm2、screen、tmux等）に対して統一されたインターフェースでタイトルを設定し、ユーザーの作業効率を向上させる。特にリモートサーバーへのSSH接続や複数プロジェクトの同時作業時に、どのターミナルがどの作業用かを即座に識別できる。

**機能の利用シーン**：
- コマンド実行時に実行中のコマンド名をタイトルに表示したい場合
- プロンプト表示時に現在のディレクトリやユーザー情報をタイトルに表示したい場合
- テーマやプラグインからカスタムタイトルを設定したい場合

**主要な処理内容**：
1. ターミナルタイプ（`$TERM`変数）を判定する
2. タイプに応じたエスケープシーケンスを使用してタイトルを設定する
3. タブタイトル（短縮版）とウィンドウタイトル（完全版）を別々に設定する

**関連システム・外部連携**：
- xterm系ターミナル（xterm、rxvt、konsole、alacritty、st、foot、contour、wezterm等）
- screen/tmux
- iTerm2
- Apple Terminal
- terminfo対応ターミナル

**権限による制御**：特になし。ただし、`DISABLE_AUTO_TITLE`環境変数がtrueの場合、自動タイトル設定は無効化される。

## 関連画面

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

## 機能種別

ターミナル制御 / エスケープシーケンス出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| short_tab_title | string | Yes | タブタイトル（短縮版） | なし |
| long_window_title | string | No | ウィンドウタイトル（完全版）。省略時は$1を使用 | なし |

### 入力データソース

- 環境変数: `$TERM`, `$TERM_PROGRAM`, `$INSIDE_EMACS`
- terminfo: `$terminfo[fsl]`, `$terminfo[tsl]`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| エスケープシーケンス | string | ターミナルに送信するタイトル設定コマンド |

### 出力先

- 標準出力（ターミナルエミュレータが解釈）

## 処理フロー

### 処理シーケンス

```
1. ローカルオプション設定
   └─ setopt localoptions nopromptsubst
2. Emacs内実行チェック
   └─ INSIDE_EMACS != vterm なら即座にreturn
3. 引数処理
   └─ $2が未設定なら$1を代入
4. ターミナルタイプ判定
   ├─ xterm系: OSC 2（ウィンドウ名）とOSC 1（タブ名）を出力
   ├─ screen/tmux: screen hardstatusを設定
   ├─ iTerm.app: OSC 2とOSC 1を出力
   └─ その他: terminfoを使用（対応していれば）
```

### フローチャート

```mermaid
flowchart TD
    A[title関数開始] --> B{INSIDE_EMACS?}
    B -->|Yes かつ != vterm| C[return]
    B -->|No または vterm| D[$2未設定?]
    D -->|Yes| E[$2 = $1]
    D -->|No| F[$2をそのまま使用]
    E --> G{$TERMタイプ判定}
    F --> G
    G -->|xterm/putty/rxvt/konsole/alacritty/st/foot/contour/wezterm| H[OSC 2,1を出力]
    G -->|screen/tmux| I[screen hardstatus出力]
    G -->|その他| J{iTerm.app?}
    J -->|Yes| H
    J -->|No| K{terminfo対応?}
    K -->|Yes| L[terminfo経由で出力]
    K -->|No| M[何もしない]
    H --> N[終了]
    I --> N
    L --> N
    M --> N
    C --> N
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Emacs除外 | Emacs内ではvterm以外タイトル設定を行わない | INSIDE_EMACS環境変数設定時 |
| BR-02 | デフォルト引数 | ウィンドウタイトル省略時はタブタイトルを使用 | $2未指定時 |
| BR-03 | プロンプト展開無効 | タイトル設定時はプロンプト変数展開を無効化 | 常時 |

### 計算ロジック

該当なし

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 非対応ターミナル | terminfoにfsl/tslがないターミナル | 何も出力せずに終了 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- エスケープシーケンス出力は瞬時（ミリ秒単位）で完了すること
- precmd/preexecフックで頻繁に呼び出されるため、オーバーヘッドを最小限に

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

- タイトルに含まれる特殊文字（%等）はエスケープ処理される（`:q`修飾子）
- 悪意あるエスケープシーケンスの注入を防ぐためnopromptsubstを設定

## 備考

- screen環境ではウィンドウタイトルは使用されず、タブタイトル（hardstatus）のみが設定される
- Apple Terminalはウィンドウとタブを別々に設定できないため、OSC 7（cwd通知）と組み合わせて使用される

---

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

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

### 推奨読解順序

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

title関数では複雑なデータ構造は使用しないが、エスケープシーケンスの理解が重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | termsupport.zsh | `lib/termsupport.zsh` | 1-8行目のコメントでエスケープシーケンスの参照URLを確認 |

**読解のコツ**:
- OSC（Operating System Command）シーケンス: `\e]N;text\a` 形式（Nはコード番号）
- OSC 1: アイコン名/タブ名
- OSC 2: ウィンドウタイトル
- screen hardstatus: `\ek...\e\\` 形式

#### Step 2: title関数の実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | termsupport.zsh | `lib/termsupport.zsh` | 9-39行目のtitle関数本体 |

**主要処理フロー**:
1. **9-10行目**: 関数定義とローカルオプション設定
2. **12-13行目**: Emacs内実行のチェック（vterm以外は早期return）
3. **15-17行目**: $2が未設定なら$1を代入（`: ${2=$1}`構文）
4. **19-23行目**: xterm系ターミナルの処理（OSC 2とOSC 1を出力）
5. **24-26行目**: screen/tmuxの処理（hardstatusを設定）
6. **27-37行目**: その他ターミナルの処理（iTerm.appチェック、terminfo使用）

**読解のコツ**:
- `print -Pn`は改行なし、プロンプト展開あり（ただしnopromptsubstで無効化）
- `${2:q}`は変数の内容をクォートしてエスケープ
- `${+terminfo[fsl]}`はterminfoにエントリが存在するかチェック

#### Step 3: 呼び出し元を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | termsupport.zsh | `lib/termsupport.zsh` | 41-46行目のデフォルトタイトル設定 |
| 3-2 | termsupport.zsh | `lib/termsupport.zsh` | 49-52行目のomz_termsupport_precmd |
| 3-3 | termsupport.zsh | `lib/termsupport.zsh` | 55-103行目のomz_termsupport_preexec |

**主要処理フロー**:
- **41行目**: `ZSH_THEME_TERM_TAB_TITLE_IDLE="%15<..<%~%<<"`（15文字に切り詰めたPWD）
- **42行目**: `ZSH_THEME_TERM_TITLE_IDLE="%n@%m:%~"`（ユーザー@ホスト:パス）
- **44-46行目**: Apple Terminalではホスト名のみ（ディレクトリはOSC 7で表示）

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

```
omz_termsupport_precmd (precmdフック)
    │
    └─ title $ZSH_THEME_TERM_TAB_TITLE_IDLE $ZSH_THEME_TERM_TITLE_IDLE

omz_termsupport_preexec (preexecフック)
    │
    └─ title $CMD "%100>...>${LINE}%<<"

テーマ/プラグイン
    │
    └─ title "カスタムタイトル" "カスタムウィンドウタイトル"
```

### データフロー図

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

$1 (タブタイトル) ─────────▶                                ┌─ \e]1;{title}\a (タブ)
                             title()
$2 (ウィンドウタイトル) ───▶  エスケープシーケンス生成 ────▶├─ \e]2;{title}\a (ウィンドウ)
                                                            │
$TERM ─────────────────────▶  ターミナルタイプ判定          └─ \ek{title}\e\\ (screen)

$TERM_PROGRAM ─────────────▶
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| termsupport.zsh | `lib/termsupport.zsh` | ソース | title関数およびターミナルサポートのメイン実装 |
