# 機能設計書 64-LSPサポート

## 概要

本ドキュメントは、Doom EmacsにおけるLSP（Language Server Protocol）サポートモジュールの機能設計を記述する。本モジュールはlsp-modeまたはeglotを介してLSPサーバーとの連携機能を提供する。

### 本機能の処理概要

LSPサポートモジュールは、Language Server Protocolを通じてコード補完、定義ジャンプ、リファレンス検索、診断（エラー/警告表示）、リファクタリングなどのIDE機能を提供する。lsp-mode（デフォルト）とeglot（+eglotフラグ）の両方をサポートし、GC最適化やサーバー遅延シャットダウンなどのパフォーマンス最適化も含む。

**業務上の目的・背景**：
現代のソフトウェア開発において、IDE級のコード支援機能は生産性向上に不可欠である。LSPは言語サーバーとエディタの間の標準プロトコルを定義し、多様な言語に対して一貫した開発体験を提供する。本モジュールにより、Doom Emacsユーザーは主要なプログラミング言語でリッチなコード編集機能を利用できる。

**機能の利用シーン**：
- コード入力時のリアルタイム補完候補の表示
- 関数やクラスの定義へのジャンプ
- シンボルの使用箇所（リファレンス）の検索
- 構文エラーや警告のリアルタイム表示
- 変数・関数のリネームなどリファクタリング
- ホバー時のドキュメント表示

**主要な処理内容**：
1. 言語サーバーの起動・接続管理
2. コード補完（completion）機能の提供
3. 定義・参照・実装ジャンプ
4. 診断（diagnostics）の表示連携
5. コードアクション・リファクタリング
6. サーバーシャットダウンの遅延管理
7. GC/IOパフォーマンス最適化

**関連システム・外部連携**：
- lsp-mode：LSPクライアント実装（デフォルト）
- eglot：Emacs組み込みLSPクライアント（+eglotフラグ）
- lsp-ui：UIコンポーネント（ドキュメント表示、peek等）
- 各種補完フレームワーク（company/corfu）
- flycheck/flymake：診断表示

**権限による制御**：
本機能に権限による制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 7 | Corfu | API連携 | lsp-completion-at-point連携 |
| 8 | Company | API連携 | company-capf連携 |

## 機能種別

IDE機能統合 / コード支援 / 外部サーバー連携

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| +lsp-defer-shutdown | integer/nil | No | サーバーシャットダウン遅延秒数（デフォルト:3） | 0以上の整数またはnil |

### 入力データソース

- バッファ内のソースコード
- プロジェクトルート検出
- LSPサーバーからの応答

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| completions | list | 補完候補リスト |
| diagnostics | list | 診断結果（エラー/警告） |
| locations | list | 定義・参照の位置情報 |
| hover-info | string | ホバー時のドキュメント |

### 出力先

- 補完ポップアップ
- 診断表示（gutter, modeline, overlay）
- ミニバッファ（eldoc）
- lsp-ui-doc ポップアップ

## 処理フロー

### 処理シーケンス

```
1. lsp! コマンド呼び出し（モードフック等から）
   └─ lsp-mode または eglot を起動

2. LSPサーバー接続
   ├─ ワークスペース検出
   ├─ サーバープロセス起動
   └─ capabilities ネゴシエーション

3. 補完・診断等の機能提供
   ├─ textDocument/completion
   ├─ textDocument/definition
   ├─ textDocument/references
   └─ textDocument/publishDiagnostics

4. バッファクローズ時
   └─ +lsp-defer-shutdown による遅延シャットダウン
```

### フローチャート

```mermaid
flowchart TD
    A[ファイルオープン] --> B{LSPモード有効?}
    B -->|No| Z[通常編集]
    B -->|Yes| C{+eglot フラグ?}
    C -->|Yes| D[eglot-ensure]
    C -->|No| E[lsp!]
    D --> F[サーバー接続]
    E --> F
    F --> G{サーバー存在?}
    G -->|No| H[インストール案内]
    G -->|Yes| I[capabilities取得]
    I --> J[補完/診断有効化]
    J --> K[編集作業]
    K --> L{バッファクローズ?}
    L -->|No| K
    L -->|Yes| M{他バッファあり?}
    M -->|Yes| K
    M -->|No| N[遅延シャットダウン]
    N --> O{タイムアウト?}
    O -->|Yes| P[サーバー停止]
    O -->|No| Q{新バッファ?}
    Q -->|Yes| K
    Q -->|No| O
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | 遅延シャットダウン | 最後のバッファクローズ後、+lsp-defer-shutdown秒待機してからサーバー停止 | バッファが0になった時 |
| BR-02 | GC閾値調整 | LSP使用中はgcmh-high-cons-thresholdを2倍に | +lsp-optimization-mode有効時 |
| BR-03 | IO最適化 | read-process-output-maxを1MBに設定 | +lsp-optimization-mode有効時 |
| BR-04 | flycheck優先 | ユーザー設定のflycheck-checkerは上書きしない | flycheck-checker設定済み時 |
| BR-05 | corfu連携 | corfuモジュール使用時はlsp-completion-provider :noneに設定 | modulep! :completion corfu |

### 計算ロジック

特になし。

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

本機能はデータベースを使用しない。ただし、LSPセッションファイルがdoom-profile-cache-dirに保存される。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | サーバー未インストール | LSPサーバーが見つからない | lsp-install-server案内 |
| - | 接続タイムアウト | サーバー起動タイムアウト | エラーログ出力 |
| - | プロトコルエラー | LSPレスポンスエラー | エラー表示、処理継続 |

### リトライ仕様

サーバー接続失敗時の自動リトライは行わない。

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

該当なし。

## パフォーマンス要件

- 補完レスポンスは200ms以内を目標
- GCスパイクによるフリーズを回避
- read-process-output-maxの最適化

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

- LSPサーバーのインストールディレクトリはdoom-profile-data-dir配下
- セッションファイルのパスをdoom-profile-cache-dir配下に隔離

## 備考

- +eglotフラグでeglotを使用（Emacs組み込み、軽量）
- +peekフラグでlsp-ui-peekを有効化
- +boosterフラグでemacs-lsp-boosterを使用（実験的）

---

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

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

### 推奨読解順序

#### Step 1: モジュール構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/tools/lsp/config.el` | +lsp-defer-shutdown変数、実装選択ロジック（49-51行目） |

**読解のコツ**:
- `modulep! +eglot` でeglot/lsp-modeの選択が決定
- 両実装の設定ファイルが別ファイルに分離されている

#### Step 2: 共通最適化を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/tools/lsp/config.el` | +lsp-optimization-mode（19-43行目） |

**主要処理フロー**:
- **26-28行目**: デフォルト値の保存と復元
- **31-34行目**: read-process-output-maxを1MBに設定
- **36-42行目**: gcmh-high-cons-thresholdを2倍に設定

#### Step 3: lsp-mode実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | +lsp.el | `modules/tools/lsp/+lsp.el` | lsp-mode use-package設定（14-170行目） |
| 3-2 | +lsp.el | `modules/tools/lsp/+lsp.el` | lsp-ui設定（173-210行目） |

**主要処理フロー**:
- **17-19行目**: セッション/サーバーインストールパスの設定
- **65-70行目**: set-lookup-handlers!による定義ジャンプ連携
- **101-124行目**: 遅延シャットダウンのadvice実装
- **147-149行目**: corfu連携設定

#### Step 4: eglot実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | +eglot.el | `modules/tools/lsp/+eglot.el` | eglot use-package設定（3-61行目） |
| 4-2 | +eglot.el | `modules/tools/lsp/+eglot.el` | eglot-booster連携（64-74行目） |

**主要処理フロー**:
- **7-8行目**: eglot-sync-connect, eglot-autoshutdown設定
- **25-30行目**: set-lookup-handlers!による定義ジャンプ連携
- **43-61行目**: 遅延シャットダウンのadvice実装

#### Step 5: autoload関数を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | common.el | `modules/tools/lsp/autoload/common.el` | 共通autoload関数 |
| 5-2 | lsp-mode.el | `modules/tools/lsp/autoload/lsp-mode.el` | lsp-mode固有autoload |
| 5-3 | eglot.el | `modules/tools/lsp/autoload/eglot.el` | eglot固有autoload |

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

```
lsp! (各言語モードのlocal-vars-hookから)
    │
    └─ [lsp-mode]
           │
           ├─ lsp-mode
           │      └─ lsp--start-workspace
           │
           ├─ +lsp-optimization-mode
           │      ├─ setq-default read-process-output-max
           │      └─ setq-default gcmh-high-cons-threshold
           │
           └─ lsp-completion-mode (corfu連携時)

eglot-ensure (各言語モードのlocal-vars-hookから)
    │
    └─ [eglot]
           │
           ├─ eglot--managed-mode
           │      └─ eglot--connect
           │
           └─ +lsp-optimization-mode
```

### データフロー図

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

ソースコード ───▶ LSPクライアント ───▶ LSPサーバー
                       │                    │
                       │   JSON-RPC通信     │
                       │◀──────────────────│
                       │
                       ▼
              ┌─────────────────────┐
              │ 補完/診断/定義/参照 │
              └─────────────────────┘
                       │
           ┌───────────┼───────────┐
           ▼           ▼           ▼
    company/corfu  flycheck   xref/lookup
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/tools/lsp/config.el` | ソース | メイン設定、最適化モード |
| +lsp.el | `modules/tools/lsp/+lsp.el` | ソース | lsp-mode実装 |
| +eglot.el | `modules/tools/lsp/+eglot.el` | ソース | eglot実装 |
| common.el | `modules/tools/lsp/autoload/common.el` | ソース | 共通autoload関数 |
| lsp-mode.el | `modules/tools/lsp/autoload/lsp-mode.el` | ソース | lsp-mode autoload |
| eglot.el | `modules/tools/lsp/autoload/eglot.el` | ソース | eglot autoload |
| doctor.el | `modules/tools/lsp/doctor.el` | 診断 | 設定診断 |
| packages.el | `modules/tools/lsp/packages.el` | 設定 | 依存パッケージ定義 |
