# 機能設計書 41-ワークスペース管理（タブ風）

## 概要

本ドキュメントは、Doom Emacsにおけるワークスペース管理機能（タブ風）の設計仕様を記述する。persp-modeを基盤として、複数のワークスペースを管理し、プロジェクト単位でのバッファ分離、セッション永続化、フレーム連携などを実現する。

### 本機能の処理概要

**業務上の目的・背景**：開発作業では複数のプロジェクトや作業コンテキストを同時に扱う必要がある。従来のEmacsではバッファが全てフラットに管理され、多くのバッファが開かれると目的のバッファを見つけることが困難になる。本機能は、ワークスペース（perspective）という概念を導入し、関連するバッファをグループ化することで、コンテキストの切り替えを効率化し、開発者の生産性を向上させる。

**機能の利用シーン**：
- 複数のプロジェクトを並行して作業する場合
- 異なるタスク（コーディング、ドキュメント作成、デバッグ）を切り替える場合
- Emacsセッションを再起動しても作業状態を復元したい場合
- フレーム（ウィンドウ）ごとに独立したワークスペースを維持したい場合

**主要な処理内容**：
1. ワークスペースの作成・削除・切り替え・リネーム
2. プロジェクト切り替え時の自動ワークスペース作成
3. バッファのワークスペースへの自動登録
4. セッションの保存・復元（永続化）
5. フレームごとのワークスペース管理
6. winner-modeとの連携によるウィンドウ構成履歴の管理
7. tab-barとの統合
8. EvilモードのExコマンドとの統合

**関連システム・外部連携**：
- persp-mode: ワークスペース管理の基盤パッケージ
- projectile: プロジェクト検出・管理との連携
- winner-mode: ウィンドウ構成の履歴管理
- tab-bar-mode: タブバーとの統合
- magit: Gitステータスバッファの保存・復元
- eshell/compilation-mode: 特殊バッファの保存・復元

**権限による制御**：特になし（全ユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Doom Dashboard | 補助機能 | セッション復元機能、ワークスペース連携 |
| 2 | Treemacs | 補助機能 | persp-mode連携によるワークスペーススコープ |
| 10 | Workspaces | 主機能 | persp-modeによるワークスペース管理、バッファ分離 |
| 11 | Tabs | 補助機能 | ワークスペース内バッファのタブ表示 |

## 機能種別

セッション管理 / 状態管理 / UI制御

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| name | string | No | ワークスペース名 | 空文字列不可、persp-nil-name（"none"）は使用不可 |
| index | integer | No | ワークスペースの番号（0-based） | 0以上の整数 |
| auto-create-p | boolean | No | 存在しない場合に自動作成するか | - |
| clone-p | boolean | No | 現在のワークスペースをクローンするか | - |

### 入力データソース

- ユーザーのキーボード入力（インタラクティブコマンド）
- Exコマンド（:tabnew, :tabclose等）
- projectile/counsel-projectileからのプロジェクト切り替えイベント
- フレーム作成・削除イベント

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| workspace-name | string | 現在のワークスペース名 |
| workspace-list | list | 全ワークスペース名のリスト |
| buffer-list | list | 現在のワークスペースに属するバッファのリスト |
| tabline | string | ミニバッファに表示されるタブライン |

### 出力先

- ミニバッファ（ワークスペースリスト表示）
- エコーエリア（操作結果メッセージ）
- セッションファイル（`~/.config/doom/workspaces/autosave`）

## 処理フロー

### 処理シーケンス

```
1. ワークスペース初期化（persp-mode起動時）
   └─ mainワークスペースの作成、nilワークスペースからの退避
2. バッファ追加時
   └─ doom-switch-buffer-hookで現在のワークスペースにバッファを登録
3. プロジェクト切り替え時
   └─ プロジェクト名でワークスペースを検索または作成し、切り替え
4. ワークスペース切り替え時
   └─ winner履歴の保存→persp切り替え→winner履歴の復元
5. セッション終了時
   └─ 実バッファがある場合のみ自動保存
```

### フローチャート

```mermaid
flowchart TD
    A[ワークスペース操作開始] --> B{操作種別}
    B -->|新規作成| C[+workspace/new]
    B -->|切り替え| D[+workspace/switch-to]
    B -->|削除| E[+workspace/kill]
    B -->|プロジェクト切り替え| F[+workspaces-switch-to-project-h]

    C --> G{既存チェック}
    G -->|存在する| H[エラー表示]
    G -->|存在しない| I[persp-add-new]
    I --> J[フォールバックバッファ表示]
    J --> K[タブライン更新]

    D --> L{存在チェック}
    L -->|存在しない & auto-create| M[ワークスペース作成]
    L -->|存在しない & !auto-create| N[エラー表示]
    L -->|存在する| O[persp-frame-switch]
    O --> P[winner履歴復元]
    P --> K

    E --> Q{保護チェック}
    Q -->|保護対象| R[エラー表示]
    Q -->|削除可能| S[persp-kill]
    S --> T[次のワークスペースに切り替え]
    T --> K

    F --> U{ワークスペース動作設定}
    U -->|t/non-empty| V[プロジェクト用ワークスペース作成/切り替え]
    U -->|nil| W[現在のワークスペースをリネーム]
    V --> K
    W --> K
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | mainワークスペース保護 | "main"ワークスペースは削除・リネーム不可 | 常時 |
| BR-02 | nilワークスペース禁止 | persp-nil-nameへの直接アクセスを防止 | 常時 |
| BR-03 | プロジェクトワークスペース | プロジェクト切り替え時に同名ワークスペースがあれば再利用 | +workspaces-on-switch-project-behavior != nil |
| BR-04 | フレーム連携 | 新規フレームには独自のワークスペースを割り当て | インタラクティブフレーム作成時 |
| BR-05 | 自動保存 | 実バッファがある場合のみセッションを自動保存 | Emacs終了時 |

### 計算ロジック

ワークスペースID生成:
```elisp
;; 既存の#N形式ワークスペースから最大値を取得し、+1
(cl-loop for name in (+workspace-list-names)
         when (string-match-p "^#[0-9]+$" name)
         maximize (string-to-number (substring name 1)) into max
         finally return (if max (1+ max) 1))
```

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

### 操作別データベース影響一覧

本機能はデータベースを使用しない。セッションデータはファイルシステムに保存される。

| 操作 | 対象ファイル | 操作種別 | 概要 |
|-----|-------------|---------|------|
| セッション保存 | autosave | WRITE | ワークスペース状態の永続化 |
| セッション復元 | autosave | READ | 保存されたワークスペースの復元 |
| 個別保存 | _workspaces | WRITE | 個別ワークスペースの保存 |
| 個別読込 | _workspaces | READ | 個別ワークスペースの読込 |

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | user-error | 保護されたワークスペースの削除・リネーム試行 | エラーメッセージ表示、処理中断 |
| - | user-error | 存在しないワークスペースへの切り替え | エラーメッセージ表示、処理中断 |
| - | user-error | 同名ワークスペースの作成 | エラーメッセージ表示、処理中断 |
| - | user-error | 他フレームで表示中のワークスペースの削除 | エラーメッセージ表示、処理中断 |

### リトライ仕様

リトライ処理は実装されていない。

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

トランザクション処理は不要（ファイルシステムへの単純な書き込みのため）。

## パフォーマンス要件

- ワークスペース切り替え: 即座（100ms以内）
- セッション保存: バックグラウンドで実行
- セッション復元: 保存されたバッファ数に依存

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

- TRAMPバッファは永続化対象外（セキュリティとパフォーマンスの観点）
- セッションファイルはユーザーのプロファイルディレクトリに保存

## 備考

- `+workspaces-main`変数でメインワークスペース名をカスタマイズ可能（デフォルト: "main"）
- `+workspaces-switch-project-function`でプロジェクト切り替え後の動作をカスタマイズ可能
- `+workspaces-on-switch-project-behavior`でプロジェクト切り替え時のワークスペース動作を制御

---

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

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

### 推奨読解順序

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

persp-modeのperspective（パースペクティブ）構造体がワークスペースの実体である。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/ui/workspaces/config.el` | 変数定義（+workspaces-main, +workspaces-data-file等） |

**読解のコツ**: `defvar`で定義されている変数がモジュールの設定ポイント。persp-modeの設定は`use-package!`ブロック内の`setq`で行われている。

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

ワークスペース操作のエントリーポイントは`autoload/workspaces.el`に定義されている。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | workspaces.el | `modules/ui/workspaces/autoload/workspaces.el` | コマンド定義（+workspace/new, +workspace/switch-to等） |

**主要処理フロー**:
1. **32-49行目**: 述語関数（+workspace-p, +workspace-exists-p, +workspace-contains-buffer-p）
2. **51-78行目**: ゲッター関数（+workspace-current, +workspace-get, +workspace-list等）
3. **98-200行目**: アクション関数（+workspace-load, +workspace-save, +workspace-new等）
4. **206-441行目**: インタラクティブコマンド（+workspace/new, +workspace/switch-to等）

#### Step 3: persp-mode設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.el | `modules/ui/workspaces/config.el` | persp-modeの設定と初期化フック |

**主要処理フロー**:
- **39-54行目**: persp-modeの基本設定
- **61-69行目**: nilワークスペース回避フック
- **71-104行目**: mainワークスペース初期化、uniquifyとの競合回避
- **129-138行目**: バッファ自動登録フック
- **171-177行目**: フレームごとのワークスペース管理設定

#### Step 4: Evil連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | evil.el | `modules/ui/workspaces/autoload/evil.el` | EvilのExコマンド定義 |

**主要処理フロー**:
- **5-39行目**: :tabnew, :tabclose等のExコマンドラッパー定義

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

```
+workspace/new (ユーザーコマンド)
    │
    ├─ +workspace-exists-p (存在チェック)
    │      └─ +workspace-list-names
    │             └─ persp-names-cache
    │
    ├─ +workspace-switch (切り替え実行)
    │      └─ persp-frame-switch
    │
    └─ +workspace/display (タブライン表示)
           └─ +workspace--tabline

+workspaces-switch-to-project-h (プロジェクト切り替えフック)
    │
    ├─ doom-project-name
    │
    ├─ +workspace-get (既存ワークスペース検索)
    │
    ├─ +workspace-new (新規作成)
    │      └─ persp-add-new
    │
    └─ +workspace-switch
           └─ persp-frame-switch
```

### データフロー図

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

ユーザー操作          ┌──────────────────────┐
(キーバインド)   ───▶ │ +workspace/* コマンド │ ───▶ ミニバッファ表示
                      └──────────────────────┘        (タブライン)
                               │
                               ▼
                      ┌──────────────────────┐
                      │  persp-mode API       │
                      │  (persp-add-new等)    │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │  *persp-hash*         │ ───▶ セッションファイル
                      │  (ワークスペース状態)  │        (autosave)
                      └──────────────────────┘
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/ui/workspaces/config.el` | ソース | モジュール設定、persp-mode初期化 |
| workspaces.el | `modules/ui/workspaces/autoload/workspaces.el` | ソース | コマンド・ライブラリ関数定義 |
| evil.el | `modules/ui/workspaces/autoload/evil.el` | ソース | Evil Exコマンド定義 |
| packages.el | `modules/ui/workspaces/packages.el` | 設定 | 依存パッケージ定義 |
| test-workspaces.el | `modules/ui/workspaces/test/test-workspaces.el` | テスト | ユニットテスト |
