# 機能設計書 30-vim-lsp連携

## 概要

本ドキュメントは、space-vimにおけるvim-lsp連携機能の設計仕様を定義する。

### 本機能の処理概要

vim-lspは、Pure Vimscriptで実装されたLanguage Server Protocol（LSP）クライアントである。space-vimでは、+tools/lspレイヤーでg:spacevim_lsp_engine='vim_lsp'を設定することで、vim-lspを有効化し、多言語に対応したLSP機能（補完、診断、定義ジャンプ、リファレンス検索等）を提供する。

**業務上の目的・背景**：vim-lspはPure Vimscriptで実装されているため、Node.js等の外部依存がなく、環境構築が容易である。また、asyncomplete.vimとの連携により、補完機能も充実している。vim-lsp-settingsを使用することで、Language Serverの自動インストール・設定が可能。

**機能の利用シーン**：
- 外部依存を最小限にしたLSP環境構築
- asyncomplete.vimとの組み合わせによる補完
- vim-lsp-settingsによるLanguage Serverの自動設定
- ALE連携による診断表示

**主要な処理内容**：
1. +tools/lspレイヤーでg:spacevim_lsp_engine='vim_lsp'設定時にプラグインを登録
2. 各言語のLanguage Serverを登録（rls, go-langserver, pyls等）
3. which-keyとの連携でSPC lキーマッピングを動的に設定
4. vim-lsp-settingsによるLanguage Serverの自動インストール

**関連システム・外部連携**：
- prabirshrestha/vim-lsp プラグイン
- prabirshrestha/async.vim（非同期処理）
- mattn/vim-lsp-settings（Language Server自動設定）
- rhysd/vim-lsp-ale（ALE連携）

**権限による制御**：特になし

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 9 | LSP診断画面 | 主機能 | vim-lspによるLSP診断情報の表示 |

## 機能種別

LSP連携 / コード補完 / 診断

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g:spacevim_lsp_engine | String | No | LSPエンジン選択 | vim_lsp |
| g:lsp_diagnostics_enabled | Number | No | 診断有効化 | 0/1, デフォルト: 1 |

### 入力データソース

- ユーザー入力（キー入力）
- Language Server

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 診断情報 | List | エラー/警告/情報/ヒント |
| 定義ジャンプ先 | Location | シンボル定義位置 |
| リファレンス | List | シンボル参照一覧 |
| ホバー情報 | String | シンボル情報 |

### 出力先

- サインカラム
- Quickfix/Location List
- プレビューウィンドウ/フローティングウィンドウ

## 処理フロー

### 処理シーケンス

```
1. +tools/lspレイヤー読み込み
   └─ packages.vimでvim-lspプラグイン登録
2. config.vim実行
   └─ s:vim_lsp()で設定、Language Server登録
3. which-key連携
   └─ SPC lキーマップを動的に設定
4. ユーザー操作
   └─ 定義ジャンプ、リファレンス検索等
```

### フローチャート

```mermaid
flowchart TD
    A[Vim起動] --> B[+tools/lspレイヤー読み込み]
    B --> C{g:spacevim_lsp_engine?}
    C -->|vim_lsp| D[vim-lspプラグイン登録]
    D --> E[async.vim登録]
    E --> F[vim-lsp-settings登録]
    F --> G{ALEレイヤー有効?}
    G -->|Yes| H[vim-lsp-ale登録]
    G -->|No| I[ALE連携なし]
    H --> J[config.vim s:vim_lsp実行]
    I --> J
    J --> K[g:lsp_diagnostics_enabled設定]
    K --> L{rls存在?}
    L -->|Yes| M[Rust LSP登録]
    L -->|No| N[次の言語チェック]
    M --> N
    N --> O{which-keyレイヤー有効?}
    O -->|Yes| P[SPC lキーマップ動的設定]
    O -->|No| Q[標準キーマップ]
    P --> R[ユーザー操作待ち]
    Q --> R
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-30-01 | LSPエンジン選択 | g:spacevim_lsp_engine='vim_lsp'で有効化 | プラグイン登録時 |
| BR-30-02 | Language Server自動登録 | executable()でサーバー存在確認後に登録 | lsp_setup時 |
| BR-30-03 | which-key動的連携 | vim_lsp選択時はSPC lキーマップを動的に変更 | 常時 |

### 計算ロジック

なし

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

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

データベース操作なし

### テーブル別操作詳細

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-30-01 | LSサーバー未検出 | Language Serverがインストールされていない | vim-lsp-settingsでインストール |
| E-30-02 | 定義未検出 | 定義が見つからない | floating windowでメッセージ表示 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

- async.vimによる非同期処理
- Pure Vimscript実装で軽量

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

なし

## 備考

- Pure Vimscript実装で外部依存なし
- vim-lsp-settingsでLanguage Server自動インストール
- ALE連携可能

---

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

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

### 推奨読解順序

#### Step 1: プラグイン登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | packages.vim | `layers/+tools/lsp/packages.vim` | vim-lspプラグイン登録 |

**読解のコツ**: s:vim_lsp()関数内でvim-lsp関連プラグインを登録。

**主要処理フロー**:
- **11-18行目**: `s:vim_lsp()` - vim-lsp関連プラグイン登録
- **12行目**: `MP 'prabirshrestha/async.vim'` - 非同期処理ライブラリ
- **13行目**: `MP 'prabirshrestha/vim-lsp'` - vim-lsp本体
- **14行目**: `MP 'mattn/vim-lsp-settings'` - Language Server自動設定
- **15-17行目**: ALEレイヤー有効時はvim-lsp-ale追加

#### Step 2: 設定処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.vim | `layers/+tools/lsp/config.vim` | vim-lsp設定 |

**主要処理フロー**:
- **117-135行目**: `s:vim_lsp()` - vim-lsp設定
- **119行目**: `g:lsp_diagnostics_enabled = 1` - 診断有効化
- **120-128行目**: 各言語のLanguage Server登録（rls, go-langserver, pyls）
- **129-134行目**: which-keyレイヤー有効時のキーマップ動的設定

#### Step 3: Language Server登録を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | lsp.vim | `core/autoload/spacevim/lang/lsp.vim` | Language Server登録関数 |

**主要処理フロー**:
- **1-8行目**: `spacevim#lang#lsp#register_rls()` - Rust Language Server登録
- **10-16行目**: `spacevim#lang#lsp#register_go()` - Go Language Server登録
- **18-24行目**: `spacevim#lang#lsp#register_python()` - Python Language Server登録

#### Step 4: which-key連携を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.vim | `layers/+tools/lsp/config.vim` | which-key動的キーマップ |

**主要処理フロー**:
- **137-215行目**: `s:whichkey_vim_lsp_integration()` - SPC l キーマップ定義
- **139-210行目**: vim-lsp固有のキーマップ辞書定義
- **142行目**: code-lens、code-action等の操作
- **151-161行目**: goto系（definition, declaration, type-definition等）
- **162-172行目**: preview系（peek-definition等）
- **179-188行目**: diagnostic系（next/previous diagnostic等）

#### Step 5: 定義未検出UI表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | lsp_ui.vim | `core/autoload/spacevim/lang/lsp_ui.vim` | 定義未検出時のUI |

**主要処理フロー**:
- **1-8行目**: DefinitionNotFound/NotFoundIconハイライト定義
- **9-75行目**: NeoVim用floating window実装
- **77-84行目**: Vim用popup_atcursor実装
- **87-89行目**: `spacevim#lang#lsp_ui#NotFound()` - エントリーポイント

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

```
spacevim#bootstrap()
    │
    ├─ layers/+tools/lsp/packages.vim
    │      └─ s:vim_lsp()
    │             ├─ MP 'prabirshrestha/async.vim'
    │             ├─ MP 'prabirshrestha/vim-lsp'
    │             ├─ MP 'mattn/vim-lsp-settings'
    │             └─ MP 'rhysd/vim-lsp-ale' (ALEレイヤー有効時)
    │
    ├─ layers/+tools/lsp/config.vim
    │      └─ s:vim_lsp()
    │             ├─ g:lsp_diagnostics_enabled設定
    │             ├─ autocmd User lsp_setup
    │             │      └─ spacevim#lang#lsp#register_*
    │             └─ s:whichkey_vim_lsp_integration()
    │
    ├─ core/autoload/spacevim/lang/lsp.vim
    │      ├─ register_rls()
    │      ├─ register_go()
    │      └─ register_python()
    │
    └─ core/autoload/spacevim/lang/lsp_ui.vim
           └─ spacevim#lang#lsp_ui#NotFound()
```

### データフロー図

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

キー入力 ───▶ vim-lsp ───▶ Language Server ───▶ 診断/補完/定義
    │                                              │
    ▼                                              ▼
SPC l ───▶ which-key ───▶ vim-lsp操作 ───▶ 結果表示
    │                                              │
    ▼                                              ▼
定義未検出 ───▶ lsp_ui.vim ───▶ floating window/popup
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| packages.vim | `layers/+tools/lsp/packages.vim` | ソース | プラグイン登録 |
| config.vim | `layers/+tools/lsp/config.vim` | ソース | vim-lsp設定 |
| lsp.vim | `core/autoload/spacevim/lang/lsp.vim` | ソース | Language Server登録 |
| lsp_ui.vim | `core/autoload/spacevim/lang/lsp_ui.vim` | ソース | 定義未検出UI |
