# 機能設計書 87-遅延読み込み

## 概要

本ドキュメントは、space-vimの遅延読み込み機能（spacevim#defer）の設計について記述する。この機能は、プラグインの遅延ロードによりVimの起動時間を最適化する仕組みを提供する。

### 本機能の処理概要

**業務上の目的・背景**：Vimはプラグインを多数導入すると起動時間が長くなる傾向がある。特にLSPクライアント、リンター、言語固有プラグインなどは起動時に必要ないことが多い。本機能は、Vimの`timer_start()`関数を活用して、起動直後ではなく一定時間後にプラグインをロードすることで、体感的な起動時間を短縮する。これにより、開発者はVimを素早く起動して作業を開始でき、バックグラウンドで必要なプラグインが順次ロードされる。

**機能の利用シーン**：Vim起動時の初期化処理、ファイルタイプ検出後の言語固有プラグインロード、重いプラグイン（YouCompleteMe等）の遅延ロードなど、起動時間の最適化が必要な場面で利用される。

**主要な処理内容**：
1. timer_start()による遅延コールバック登録
2. 指定ミリ秒後にspacevim#defer#{name}関数を実行
3. plug#load()によるvim-plugプラグインの動的ロード
4. 必要に応じてプラグイン固有の初期化処理を実行

**関連システム・外部連携**：vim-plug（プラグインマネージャ）との連携。各プラグインの初期化処理との連動。

**権限による制御**：特になし。g:spacevim.timerがtrueの場合に自動的に適用。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | Startify（スタート画面） | 補助機能 | spacevim#defer#defaultsによる遅延読み込み時の初期化処理 |

## 機能種別

パフォーマンス最適化 / 遅延ロード

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| timer | Number | Yes | timer_startから渡されるタイマーID | Vimが自動付与 |

### 入力データソース

- timer_start()のコールバック呼び出し
- g:spacevim.timer設定値

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| ロード状態 | void | プラグインのロード完了（戻り値なし） |

### 出力先

- Vimのランタイムパス（プラグインロード）
- g:plugsへのプラグイン状態反映

## 処理フロー

### 処理シーケンス

```
1. 起動時（またはftplugin読み込み時）
   └─ timer_start(delay, 'spacevim#defer#{name}')呼び出し
2. 指定時間経過後
   └─ タイマーコールバック実行
3. プラグインロード
   └─ s:lod()でplug#load()を呼び出し
4. 初期化処理（必要に応じて）
   └─ プラグイン固有の初期化コマンド実行
```

### フローチャート

```mermaid
flowchart TD
    A[timer_start呼び出し] --> B[指定ミリ秒待機]
    B --> C[コールバック関数実行]
    C --> D[s:lod関数呼び出し]
    D --> E{プラグイン存在?}
    E -->|Yes| F[plug#load実行]
    E -->|No| G[silent!でスキップ]
    F --> H{初期化処理必要?}
    H -->|Yes| I[初期化コマンド実行]
    H -->|No| J[処理完了]
    G --> J
    I --> J
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-87-1 | 遅延時間の階層化 | 重要度に応じて遅延時間を設定（200ms〜1000ms） | 各defer関数 |
| BR-87-2 | サイレント実行 | 存在しないプラグインはsilent!でエラー抑制 | s:lod関数 |
| BR-87-3 | タイマー条件 | g:spacevim.timerがtrueの場合のみ遅延ロード実行 | ftplugin等 |
| BR-87-4 | 再描画 | airlineロード後はredraws!で画面更新 | defer#airline |

### 計算ロジック

**遅延時間の設定例**:
- 200ms: ALE（リンター、早期に必要）
- 250ms: airline（ステータスライン）
- 300ms: Git系、言語固有（python, go, rust等）
- 400ms: programming（rainbow等）
- 500ms: defaults（traces.vim等）
- 600ms: motion（easymotion等）
- 700ms: fzf
- 800ms: fugitive
- 900ms: vimspector（デバッガ）
- 1000ms: YouCompleteMe（最も重い）

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

本機能はデータベース操作を行わない。

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | プラグイン未登録 | g:plugsにプラグインが存在しない | silent!で無視 |
| - | timer未サポート | 古いVimバージョン | g:spacevim.timer=falseで無効化 |
| - | ロードエラー | プラグイン自体のエラー | プラグインの修正が必要 |

### リトライ仕様

リトライは行わない。一度ロードを試みたら、成功・失敗に関わらず処理完了。

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

該当なし（ファイルシステムやDBへの永続化を伴わない）

## パフォーマンス要件

- 起動時間を体感的に短縮すること
- 遅延ロードにより編集開始可能になるまでの時間を最小化
- バックグラウンドロードがフォアグラウンド操作をブロックしないこと

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

- Vimのtimer機能を使用、外部通信なし
- プラグインのロードはvim-plugの標準機能を使用

## 備考

- timer_startはVim 7.4.1578以降、Neovimで利用可能
- vim-plugのplug#load()は登録済みプラグインを動的にロード
- 遅延時間は経験則に基づいて設定されており、環境により調整が必要な場合あり

---

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

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

### 推奨読解順序

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

本機能はautoload関数として実装。各関数は`spacevim#defer#{name}`の命名規則。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | defer.vim | `core/autoload/spacevim/defer.vim` | 全体構造と各関数の役割 |

**読解のコツ**: 関数名の後のコメント（例: `" 200`）は推奨される遅延時間（ミリ秒）を示す。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | defer.vim | `core/autoload/spacevim/defer.vim` | s:lod関数が共通ロード処理 |

**主要処理フロー**:
1. **1-6行目**: `s:lod()`関数 - プラグインロードのラッパー
2. **4行目**: `silent! call plug#load(l:plug)` - vim-plugによるロード

#### Step 3: 各遅延ロード関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | defer.vim | `core/autoload/spacevim/defer.vim` | 各defer関数の実装 |

**主要処理フロー**:
- **8-11行目**: `defer#ale` (200ms) - ALEリンターロード
- **13-17行目**: `defer#airline` (250ms) - ステータスラインロード＋再描画
- **19-22行目**: `defer#git` (300ms) - vim-signifyロード
- **24-30行目**: `defer#programming` (400ms) - 複数プラグイン＋EditorConfigリロード
- **32-38行目**: `defer#defaults` (500ms) - デフォルトプラグインロード
- **40-43行目**: `defer#motion` (600ms) - モーション系プラグインロード
- **45-48行目**: `defer#fzf` (700ms) - ファジーファインダーロード
- **50-53行目**: `defer#fugitive` (800ms) - Gitプラグインロード
- **55-58行目**: `defer#vimspector` (900ms) - デバッガロード
- **60-63行目**: `defer#ycm` (1000ms) - YouCompleteMeロード
- **69-83行目**: 言語固有の遅延ロード（markdown, rust, go, python）

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

```
Vim起動 / ファイルオープン
    │
    ├─ core/ftplugin/{filetype}.vim
    │      └─ timer_start(300, 'spacevim#defer#python')
    │
    └─ 指定ミリ秒後
           └─ spacevim#defer#python(timer)
                  └─ s:lod('python-mode')
                         └─ plug#load('python-mode')
```

### データフロー図

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

timer_start()        待機                           プラグイン
(delay, callback) ──▶ (指定ms) ──▶ callback実行  ──▶ ロード完了
                                       │
                                       ▼
                                    s:lod()
                                       │
                                       ▼
                                  plug#load()
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| defer.vim | `core/autoload/spacevim/defer.vim` | ソース | 遅延ロード関数群 |
| python.vim | `core/ftplugin/python.vim` | ソース | Pythonでの遅延ロード呼び出し例 |
| go.vim | `core/ftplugin/go.vim` | ソース | Goでの遅延ロード呼び出し例 |
| rust.vim | `core/ftplugin/rust.vim` | ソース | Rustでの遅延ロード呼び出し例 |
| markdown.vim | `core/ftplugin/markdown.vim` | ソース | Markdownでの遅延ロード呼び出し例 |
