# 通知設計書 14-ウィンドウタイトル設定

## 概要

本ドキュメントは、Oh My Zshのターミナルサポート機能における、ターミナルウィンドウのタイトルを現在のユーザー・ホスト・ディレクトリに自動設定する通知の設計を記載する。

### 本通知の処理概要

この通知は、ANSIエスケープシーケンス（OSC 2）を使用して、ターミナルウィンドウのタイトルを動的に更新する機能である。プロンプト表示前（precmd）とコマンド実行前（preexec）に呼び出され、現在の状態を反映したタイトルを設定する。

**業務上の目的・背景**：複数のターミナルウィンドウを同時に使用する際、各ウィンドウで作業中の内容を把握することは効率的な作業に不可欠である。ウィンドウタイトルにユーザー名、ホスト名、カレントディレクトリを表示することで、タスクバーやウィンドウ切り替え時に現在の作業コンテキストを即座に識別できる。

**通知の送信タイミング**：precmdフック（プロンプト表示前）では「user@host:directory」形式のアイドル状態タイトルを設定し、preexecフック（コマンド実行前）では実行中のコマンドラインを含むタイトルを設定する。

**通知の受信者**：ターミナルエミュレータ。OSC 2エスケープシーケンスを解釈してウィンドウタイトルを更新する。

**通知内容の概要**：アイドル時は「%n@%m:%~」（例：user@hostname:/home/user/project）、コマンド実行時は「command — full_command_line」の形式でタイトルが設定される。

**期待されるアクション**：ターミナルエミュレータがエスケープシーケンスを解釈し、ウィンドウタイトルを更新する。ユーザーはウィンドウ一覧やタスクバーで現在の作業内容を確認できる。

## 通知種別

ターミナルエスケープシーケンス（OSC 2）

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（フック実行時に即座に送信） |
| 優先度 | 低（表示最適化のための補助機能） |
| リトライ | なし |

### 送信先決定ロジック

現在のターミナルセッションに対してエスケープシーケンスを出力する。ターミナルエミュレータが対応していない場合は無視される。

## 通知テンプレート

### エスケープシーケンス形式

| 項目 | 内容 |
|-----|------|
| 送信元 | termsupport.zsh |
| エスケープシーケンス | `\e]2;${title}\a` |
| 対応ターミナル | xterm, putty, rxvt, konsole, mlterm, alacritty, st, foot, contour, wezterm, iTerm2 |

### 本文テンプレート

#### アイドル時（precmd）

```
\e]2;%n@%m:%~\a
```

展開例：`\e]2;user@hostname:/home/user/project\a`

#### コマンド実行時（preexec）

```
\e]2;%100>...>${LINE}%<<\a
```

展開例：`\e]2;git — git status\a`（100文字で切り詰め）

### Apple Terminalの特別処理

Apple Terminalではディレクトリ情報はOSC 7で表示されるため、タイトルには「%n@%m」のみが設定される。

### 添付ファイル

| ファイル名 | 形式 | 条件 | 説明 |
|----------|------|------|------|
| なし | - | - | エスケープシーケンスのため添付ファイルなし |

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| %n | ユーザー名 | $USER | Yes |
| %m | ホスト名 | $HOST | Yes |
| %~ | カレントディレクトリ（~展開） | $PWD | Yes |
| ZSH_THEME_TERM_TITLE_IDLE | アイドル時タイトルフォーマット | 設定/デフォルト | No |
| CMD | コマンド名 | preexecの第1引数 | No（preexecのみ） |
| LINE | コマンドライン全体 | preexecの第2引数 | No（preexecのみ） |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| フック | precmd | DISABLE_AUTO_TITLE != true | プロンプト表示前 |
| フック | preexec | DISABLE_AUTO_TITLE != true | コマンド実行前 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| DISABLE_AUTO_TITLE=true | タイトル自動設定を無効化 |
| INSIDE_EMACS != "" && != vterm | Emacs内（vtermを除く）では設定しない |
| 非対応ターミナル | $TERMが対応ターミナルでない場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[precmd/preexecフック実行] --> B{DISABLE_AUTO_TITLE?}
    B -->|true| C[処理終了]
    B -->|false| D{INSIDE_EMACS?}
    D -->|Yes かつ != vterm| C
    D -->|No または vterm| E[title関数呼び出し]
    E --> F{$TERM判定}
    F -->|xterm等| G[OSC 2でウィンドウタイトル設定]
    F -->|screen/tmux| H[screen hardstatus設定]
    F -->|その他| I{$TERM_PROGRAM?}
    I -->|iTerm.app| G
    I -->|その他| J{terminfo確認}
    J -->|対応| K[terminfoで設定]
    J -->|非対応| C
    G --> L[終了]
    H --> L
    K --> L
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| なし | - | データベースは使用しない |

### 更新テーブル一覧

| テーブル名 | 操作 | 概要 |
|-----------|------|------|
| なし | - | データベースは使用しない |

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| ターミナル非対応 | OSC 2を解釈できないターミナル | エスケープシーケンスは無視される（害はない） |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | なし |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 制限なし | フックごとに1回のみ実行 |

### 配信時間帯

制限なし（フック実行時に即座に送信）

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

- タイトルにはユーザー名、ホスト名、ディレクトリパスが含まれる
- 機密性の高いディレクトリ名が表示される可能性がある（スクリーンショット等で注意）
- `${1:q}`によるクォート処理でエスケープシーケンスインジェクションを防止

## 備考

- `print -Pn`を使用してプロンプト展開（%n, %m, %~）を適用
- ZSH_THEME_TERM_TITLE_IDLE変数でアイドル時のタイトルフォーマットをカスタマイズ可能
- コマンド実行時は先頭100文字で切り詰め、長いコマンドラインでも見やすく表示

---

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

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

### 推奨読解順序

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

まず、タイトルフォーマットの設定変数を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | termsupport.zsh | `lib/termsupport.zsh` | タイトルフォーマット変数の定義（41-46行目） |

**読解のコツ**: `%15<..<%~%<<`は15文字に左切り詰め、`%n@%m:%~`はzshのプロンプト展開形式。

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

処理の起点となるフック登録を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | termsupport.zsh | `lib/termsupport.zsh` | フック登録（105-110行目） |

**主要処理フロー**:
1. **107行目**: INSIDE_EMACS判定
2. **108行目**: precmdフックにomz_termsupport_precmdを登録
3. **109行目**: preexecフックにomz_termsupport_preexecを登録

#### Step 3: title関数を理解する

ウィンドウタイトル設定の中核関数を確認する。

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

**主要処理フロー**:
- **10行目**: `setopt localoptions nopromptsubst`でプロンプト展開を制御
- **13行目**: INSIDE_EMACS判定（vtermを除く）
- **17行目**: 第2引数のデフォルト値設定
- **19-23行目**: xterm系ターミナルでOSC 2/1を出力
- **21行目**: `print -Pn "\e]2;${2:q}\a"` でウィンドウタイトル設定

#### Step 4: precmd/preexecフック関数を理解する

フックから呼び出される関数を確認する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | termsupport.zsh | `lib/termsupport.zsh` | omz_termsupport_precmd関数（49-52行目） |
| 4-2 | termsupport.zsh | `lib/termsupport.zsh` | omz_termsupport_preexec関数（55-103行目） |

**主要処理フロー（preexec）**:
- **63行目**: コマンドラインを配列に分割
- **65-96行目**: fgコマンドの場合、バックグラウンドジョブのコマンドを取得
- **99-100行目**: CMDとLINE変数を設定
- **102行目**: title関数を呼び出し

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

```
シェル起動
    │
    └─ lib/termsupport.zsh (source)
           │
           ├─ add-zsh-hook precmd omz_termsupport_precmd (108行目)
           │      │
           │      └─ omz_termsupport_precmd (49-52行目)
           │             └─ title "$ZSH_THEME_TERM_TAB_TITLE_IDLE" "$ZSH_THEME_TERM_TITLE_IDLE"
           │                    └─ print -Pn "\e]2;${2:q}\a" (21行目)
           │
           └─ add-zsh-hook preexec omz_termsupport_preexec (109行目)
                  │
                  └─ omz_termsupport_preexec (55-103行目)
                         └─ title "$CMD" "%100>...>${LINE}%<<"
                                └─ print -Pn "\e]2;${2:q}\a" (21行目)
```

### データフロー図

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

$USER, $HOST ───▶ ZSH_THEME_TERM_TITLE_IDLE ───▶ title関数
$PWD                      │                          │
                          ▼                          ▼
                   プロンプト展開            \e]2;user@host:path\a
                   (%n, %m, %~)                      │
                                                    ▼
                                           ターミナルウィンドウタイトル

---

コマンドライン ───▶ CMD/LINE抽出 ───▶ title関数 ───▶ \e]2;cmd — line\a
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| termsupport.zsh | `lib/termsupport.zsh` | ソース | ターミナルタイトル設定のメイン実装 |
