# 機能設計書 27-asyncomplete連携

## 概要

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

### 本機能の処理概要

asyncomplete.vimは、Pure Vimscriptで実装された軽量な非同期補完プラグインである。space-vimでは、+completion/asyncompleteレイヤーを通じてasyncompleteを統合し、vim-lspとの連携による高度な補完機能を提供する。外部依存が少なく、Vim/NeoVim両方で動作する。

**業務上の目的・背景**：補完プラグインの中には、PythonやNode.js等の外部ランタイムを必要とするものがある。asyncompleteはPure Vimscriptで実装されているため、追加のランタイムなしで動作し、環境構築が容易である。また、vim-lspとの連携により、Language Server Protocolベースの高度な補完を実現できる。

**機能の利用シーン**：
- vim-lspと組み合わせてLSPベースの補完を使用する
- 軽量な補完環境を構築したい場合
- 外部ランタイム（Python, Node.js）を使用せず補完機能を利用する場合

**主要な処理内容**：
1. +completion/asyncompleteレイヤー有効化時にプラグインを登録
2. Tab/Shift-Tab/CRキーマッピングを設定
3. 手動トリガー補完（asyncomplete#force_refresh）をサポート
4. CompleteDoneイベントでプレビューウィンドウを自動クローズ

**関連システム・外部連携**：
- prabirshrestha/asyncomplete.vim プラグイン
- prabirshrestha/asyncomplete-lsp.vim（vim-lsp連携）
- prabirshrestha/vim-lsp

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 8 | 補完ポップアップ | 主機能 | asyncomplete.vimによる補完候補の表示 |

## 機能種別

コード補完 / 非同期処理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| g:asyncomplete_auto_popup | Number | No | 自動ポップアップ | 0/1, デフォルト: 0 |

### 入力データソース

- ユーザー入力（キー入力）
- vim-lsp（LSP補完ソース）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| 補完候補リスト | List | 補完候補の一覧 |
| ポップアップメニュー | UI | 補完候補表示UI |

### 出力先

- Vimポップアップメニュー

## 処理フロー

### 処理シーケンス

```
1. +completion/asyncompleteレイヤー読み込み
   └─ packages.vimでプラグイン登録
2. config.vim実行
   └─ キーマッピング、自動ポップアップ設定
3. ユーザー入力
   └─ Tab押下または手動トリガー
4. 補完候補取得
   └─ asyncomplete/vim-lspから候補取得
5. ポップアップ表示
   └─ 補完候補をポップアップで表示
6. 補完完了
   └─ CompleteDoneでプレビューウィンドウ自動クローズ
```

### フローチャート

```mermaid
flowchart TD
    A[Vim起動] --> B[+completion/asyncompleteレイヤー読み込み]
    B --> C[packages.vimでプラグイン登録]
    C --> D[config.vim実行]
    D --> E[キーマッピング設定]
    E --> F[g:asyncomplete_auto_popup = 0]
    F --> G[ユーザー入力待ち]
    G --> H{Tab押下?}
    H -->|Yes| I{ポップアップ表示中?}
    I -->|Yes| J[次の候補選択]
    I -->|No| K{空白の後?}
    K -->|Yes| L[Tabを挿入]
    K -->|No| M[asyncomplete#force_refresh]
    H -->|No| N{CR押下?}
    N -->|Yes| O[補完確定]
    O --> P[CompleteDone]
    P --> Q[pclose実行]
    N -->|No| G
    J --> G
    L --> G
    M --> R[ポップアップ表示]
    R --> G
    Q --> G
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-27-01 | 手動トリガー | auto_popup=0で手動トリガーモード | デフォルト |
| BR-27-02 | 空白判定 | カーソル直前が空白の場合はTabを挿入 | Tab押下時 |
| BR-27-03 | プレビュー自動クローズ | 補完完了時にプレビューウィンドウをクローズ | CompleteDone時 |

### 計算ロジック

```vim
function! s:check_back_space() abort
    let col = col('.') - 1
    return !col || getline('.')[col - 1]  =~ '\s'
endfunction
```

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

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

データベース操作なし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| E-27-01 | プラグイン未検出 | asyncompleteが存在しない | silent!で無視 |

### リトライ仕様

なし

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

該当なし

## パフォーマンス要件

- Pure Vimscriptで軽量実装
- 非同期処理により編集をブロックしない

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

なし

## 備考

- Pure Vimscript実装のため外部依存が少ない
- vim-lspとの連携が推奨
- LSPと連携可能

---

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

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

### 推奨読解順序

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

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

**読解のコツ**: asyncompleteとasyncomplete-lsp.vimの2つのプラグインを登録。

**主要処理フロー**:
- **1行目**: `MP 'prabirshrestha/asyncomplete.vim'` - asyncompleteプラグイン登録
- **2行目**: `MP 'prabirshrestha/asyncomplete-lsp.vim'` - LSP連携プラグイン登録

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

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

**主要処理フロー**:
- **1-3行目**: 基本的なTab/S-Tab/CRキーマッピング
- **5行目**: `g:asyncomplete_auto_popup = 0` - 自動ポップアップ無効
- **7-10行目**: `s:check_back_space()`関数 - カーソル直前の空白判定
- **12-16行目**: 拡張Tabキーマッピング - ポップアップ/空白/force_refreshの分岐
- **18行目**: CompleteDoneイベントでpclose

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

```
spacevim#bootstrap()
    │
    ├─ layers/+completion/asyncomplete/packages.vim
    │      ├─ MP 'prabirshrestha/asyncomplete.vim'
    │      └─ MP 'prabirshrestha/asyncomplete-lsp.vim'
    │
    └─ layers/+completion/asyncomplete/config.vim
           ├─ Tab/S-Tab/CRキーマッピング
           ├─ s:check_back_space()
           └─ CompleteDone autocmd
```

### データフロー図

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

キー入力 ───▶ asyncomplete ───▶ vim-lsp ───▶ 補完候補
    │                                           │
    ▼                                           ▼
空白判定 ───▶ force_refresh ───────────▶ ポップアップ表示
                                              │
                                              ▼
                               CompleteDone ───▶ pclose
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| packages.vim | `layers/+completion/asyncomplete/packages.vim` | ソース | プラグイン登録 |
| config.vim | `layers/+completion/asyncomplete/config.vim` | ソース | asyncomplete設定 |
