# 機能設計書 65-omz_termsupport_cwd

## 概要

本ドキュメントは、Oh My Zshのターミナルサポート機能における`omz_termsupport_cwd`関数の設計を記載する。この関数は、OSC 7エスケープシーケンスを使用して現在の作業ディレクトリをターミナルエミュレータに通知する。これにより、「新しいタブを同じディレクトリで開く」などの機能が正しく動作する。

### 本機能の処理概要

**業務上の目的・背景**：モダンなターミナルエミュレータ（iTerm2、Terminal.app、GNOME Terminal等）は、シェルの現在作業ディレクトリを認識することで、新しいタブやウィンドウを同じディレクトリで開いたり、ディレクトリをクリック可能なリンクとして表示したりする機能を提供する。この機能は、OSC 7（Operating System Command 7）エスケープシーケンスを使用して、シェルからターミナルエミュレータに現在のディレクトリを通知することで、これらの機能を有効にする。

**機能の利用シーン**：
- ターミナルで新しいタブを開く際、現在のディレクトリを引き継ぎたい場合
- ターミナルのディレクトリパスをクリックしてFinderやファイルマネージャで開きたい場合
- シンボリックリンクを含むパスでも正しいディレクトリを通知したい場合

**主要な処理内容**：
1. 現在のホスト名とパスをURLエンコードする
2. file://形式のURIを構築する
3. OSC 7エスケープシーケンスをターミナルに送信する

**関連システム・外部連携**：
- Apple Terminal.app
- iTerm2
- GNOME Terminal (libvte系)
- Konsole
- OSC 7をサポートする各種ターミナルエミュレータ

**権限による制御**：Emacs内、SSH接続時、または非対応ターミナルでは自動的に無効化される。

## 関連画面

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

## 機能種別

フック処理 / ターミナル制御 / エスケープシーケンス出力

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| なし | - | - | precmdフックとして引数なしで呼び出される | - |

### 入力データソース

- シェル変数: `$HOST`, `$PWD`
- 環境変数: `$INSIDE_EMACS`, `$SSH_CLIENT`, `$SSH_TTY`, `$TERM`, `$TERM_PROGRAM`
- 環境変数: `$KONSOLE_PROFILE_NAME`, `$KONSOLE_DBUS_SESSION`

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| OSC 7シーケンス | string | `\e]7;file://hostname/path\e\\` 形式のエスケープシーケンス |

### 出力先

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

## 処理フロー

### 処理シーケンス

```
1. 関数定義前チェック（ファイル読み込み時）
   ├─ Emacs内 → return（関数定義しない）
   ├─ SSH接続中 → return（関数定義しない）
   └─ 非対応ターミナル → return（関数定義しない）
2. omz_termsupport_cwd関数実行時
   ├─ ローカルオプション設定（unset）
   ├─ ホスト名をURLエンコード
   ├─ パスをURLエンコード
   ├─ Konsoleの場合はホスト名を空に
   └─ OSC 7エスケープシーケンスを出力
```

### フローチャート

```mermaid
flowchart TD
    A[ファイル読み込み時] --> B{INSIDE_EMACS?}
    B -->|Yes| C[return - 関数定義しない]
    B -->|No| D{SSH接続中?}
    D -->|Yes| C
    D -->|No| E{対応ターミナル?}
    E -->|No| C
    E -->|Yes| F[関数定義 & フック登録]

    G[omz_termsupport_cwd実行] --> H[ローカルオプション設定]
    H --> I[ホスト名URLエンコード]
    I --> J[パスURLエンコード]
    J --> K{Konsole?}
    K -->|Yes| L[ホスト名を空に]
    K -->|No| M[ホスト名を使用]
    L --> N[OSC 7出力]
    M --> N
    N --> O[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Emacs除外 | Emacs内では機能を無効化 | INSIDE_EMACS環境変数設定時 |
| BR-02 | SSH除外 | SSH接続時は機能を無効化 | SSH_CLIENT/SSH_TTY環境変数設定時 |
| BR-03 | 対応ターミナル判定 | 特定のターミナルタイプまたはTERM_PROGRAMでのみ有効 | 常時 |
| BR-04 | Konsole特例 | Konsoleではホスト名を含めない（エラー回避） | KONSOLE_PROFILE_NAME/KONSOLE_DBUS_SESSION設定時 |
| BR-05 | precmdフック使用 | chpwdではなくprecmdフックを使用（出力汚染防止） | 常時 |

### 計算ロジック

**file URI構築**:
```
file://[host][path]
```
- `[host]`: URLエンコードされたホスト名（Konsoleでは空）
- `[path]`: URLエンコードされた現在ディレクトリパス

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | URLエンコード失敗 | omz_urlencodeがエラーを返した場合 | return 1で終了 |

### リトライ仕様

該当なし

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

該当なし

## パフォーマンス要件

- プロンプト表示のたびに実行されるため、数ミリ秒以内で完了すること
- URLエンコード処理は高速であること

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

- パス情報がエスケープシーケンスとして送信されるため、機密性の高いディレクトリ名は注意
- SSH接続時は無効化されるため、リモートパス情報の漏洩リスクは限定的

## 備考

- OSC 7は2012年以前のlibvteでは未知のOSCとして表示されるバグがあった
- mlterm、PuTTY、rxvt、screen、termux、xtermは未知のOSCを単に無視する
- chpwdフックではなくprecmdフックを使用する理由は、スクリプトや関数が`cd -q`なしでディレクトリを変更した場合の出力汚染を防ぐため

---

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

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

### 推奨読解順序

#### Step 1: 前提条件チェックを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | termsupport.zsh | `lib/termsupport.zsh` | 112-140行目の関数定義前チェック |

**主要処理フロー**:
- **124-127行目**: Emacs内またはSSH接続時はreturn（関数定義しない）
- **129-140行目**: 対応ターミナルチェック（case文）
  - **132-133行目**: xterm系、screen系、tmux等は対応
  - **135-138行目**: Terminal.appとiTerm2は対応、その他は非対応

**読解のコツ**:
- この部分はファイル読み込み時に評価される（関数外のコード）
- returnはファイルのsourcingを中断し、以降のコードは実行されない

#### Step 2: omz_termsupport_cwd関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | termsupport.zsh | `lib/termsupport.zsh` | 147-159行目のomz_termsupport_cwd関数 |

**主要処理フロー**:
- **148行目**: `setopt localoptions unset` - 未定義変数を空として扱う
- **150-152行目**: `URL_HOST="$(omz_urlencode -P $HOST)"` - ホスト名エンコード
- **152行目**: `URL_PATH="$(omz_urlencode -P $PWD)"` - パスエンコード
- **155行目**: Konsoleの場合はURL_HOSTを空に
- **158行目**: OSC 7シーケンス出力

**読解のコツ**:
- `omz_urlencode -P`は-Pオプションでスペースを%20にエンコード
- `\e]7;`はOSC 7の開始、`\e\\`は終了（ST: String Terminator）
- `printf`を使用してprint -Pのプロンプト展開を避けている

#### Step 3: フック登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | termsupport.zsh | `lib/termsupport.zsh` | 164行目のフック登録 |

**主要処理フロー**:
- **164行目**: `add-zsh-hook precmd omz_termsupport_cwd` - precmdフックに登録

#### Step 4: 依存関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | functions.zsh | `lib/functions.zsh` | omz_urlencode関数（URLエンコード処理） |

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

```
ファイル読み込み時（lib/termsupport.zsh source）
    │
    ├─ 前提条件チェック
    │      ├─ Emacs/SSH → return（関数定義しない）
    │      └─ 非対応ターミナル → return（関数定義しない）
    │
    ├─ omz_termsupport_cwd関数定義
    │
    └─ add-zsh-hook precmd omz_termsupport_cwd

zshプロンプト表示
    │
    └─ precmdフック実行
           │
           └─ omz_termsupport_cwd()
                  │
                  ├─ omz_urlencode($HOST)
                  │
                  ├─ omz_urlencode($PWD)
                  │
                  └─ printf "\e]7;file://%s%s\e\\"
```

### データフロー図

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

$HOST ─────────────────────────▶ omz_urlencode() ──────▶ URL_HOST
  "myhost"                                                 "myhost"

$PWD ──────────────────────────▶ omz_urlencode() ──────▶ URL_PATH
  "/home/user/my project"                                  "/home/user/my%20project"

                                  omz_termsupport_cwd()
URL_HOST + URL_PATH ───────────▶  file:// URI構築 ─────▶ OSC 7シーケンス
                                                           "\e]7;file://myhost/home/user/my%20project\e\\"

$KONSOLE_PROFILE_NAME ─────────▶  Konsole判定
  (設定時はURL_HOSTを空に)
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| termsupport.zsh | `lib/termsupport.zsh` | ソース | omz_termsupport_cwd関数およびターミナルサポートのメイン実装 |
| functions.zsh | `lib/functions.zsh` | ソース | omz_urlencode関数（URLエンコード処理） |
