# 機能設計書 86-Neovim API

## 概要

本ドキュメントは、space-vimのNeovim API機能の設計について記述する。この機能は、Neovim固有のAPIを活用したフローティングウィンドウ機能のラッパーを提供する。

### 本機能の処理概要

**業務上の目的・背景**：NeovimはVimとの互換性を保ちつつ、独自の拡張APIを提供している。特にフローティングウィンドウ（floating window）機能は、ポップアップ表示やプレビュー表示など、モダンなUIを実現するために重要な機能である。本機能は、Neovim固有のAPI（nvim_create_buf、nvim_open_win等）をラップし、space-vim内の各機能から統一的なインターフェースで利用できるようにする。

**機能の利用シーン**：補完候補のプレビュー表示、ドキュメントのホバー表示、診断情報のポップアップ表示、各種情報パネルの表示など、既存のウィンドウレイアウトを崩さずに追加情報を表示したい場面で利用される。

**主要な処理内容**：
1. フローティングウィンドウ用バッファの作成（nvim_create_buf）
2. 指定位置・サイズでのフローティングウィンドウの表示（nvim_open_win）
3. ウィンドウのハイライト設定（Pmenuスタイル適用）
4. 各種レイアウトオプション（left、right、center等）の提供

**関連システム・外部連携**：Neovim本体のAPI。coc.nvim、vim-clap等のプラグインとの連携可能性。

**権限による制御**：Neovim環境でのみ動作。Vim環境では利用不可。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 18 | Terminal（ターミナル画面） | 補助機能 | Neovim固有のtermopen APIによるターミナル制御 |

## 機能種別

UI制御 / API ラッパー

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| row | Number | Yes | ウィンドウの行位置（エディタ相対） | 0以上 |
| col | Number | Yes | ウィンドウの列位置（エディタ相対） | 0以上 |
| width | Number | Yes | ウィンドウの幅 | 1以上 |
| height | Number | Yes | ウィンドウの高さ | 1以上 |

### 入力データソース

- Vimの画面サイズ（&columns, &lines）
- ステータスライン・コマンドラインの高さ（&laststatus, &cmdheight）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| win | Number | 作成されたウィンドウID |
| buf | Number | 作成されたバッファID（内部使用） |

### 出力先

- Neovimのフローティングウィンドウ

## 処理フロー

### 処理シーケンス

```
1. パラメータ設定
   └─ row, col, width, heightを計算またはプリセットから取得
2. バッファ作成
   └─ nvim_create_buf(v:false, v:true)でスクラッチバッファ作成
3. ウィンドウ作成
   └─ nvim_open_win()でフローティングウィンドウを開く
4. ウィンドウ設定
   └─ ハイライトグループ設定（Normal:Pmenu）
   └─ バッファオプション設定（nofile、nobuflisted等）
5. ウィンドウID返却
   └─ 呼び出し元にウィンドウIDを返す
```

### フローチャート

```mermaid
flowchart TD
    A[open関数呼び出し] --> B[オプション辞書作成]
    B --> C[nvim_create_buf実行]
    C --> D[nvim_open_win実行]
    D --> E[ハイライト設定]
    E --> F[バッファオプション設定]
    F --> G[ウィンドウID返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-86-1 | エディタ相対配置 | relative: 'editor'でエディタ全体を基準に配置 | すべてのウィンドウ |
| BR-86-2 | Pmenuハイライト | フローティングウィンドウにPmenuハイライトを適用 | ウィンドウ作成時 |
| BR-86-3 | スクラッチバッファ | listed=false, scratch=trueのバッファを使用 | バッファ作成時 |
| BR-86-4 | ステータスライン考慮 | down/right等で&laststatus, &cmdheightを考慮 | 下部・右部配置時 |

### 計算ロジック

**位置計算の例（rightメソッド）**:
```vim
let width = &columns / 2
let gap = &cmdheight
if &laststatus > 0
  let gap += 1
endif
let height = &lines - gap
let row = 0
let col = &columns / 2
```

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

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

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | Vim環境エラー | NeovimではなくVimで実行 | has('nvim')でチェック |
| - | API未サポート | 古いNeovimバージョン | Neovimをアップグレード |
| - | サイズ不正 | width/heightが0以下 | 正の値を指定 |

### リトライ仕様

リトライは不要。エラー発生時はユーザーがパラメータを修正して再度呼び出す。

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

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

## パフォーマンス要件

- ウィンドウ作成は即座（50ms以内）に完了すること
- 既存の編集操作に影響を与えないこと

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

- Neovim内部APIのみを使用、外部通信なし
- フローティングウィンドウは一時的なUI要素であり、永続的な影響なし

## 備考

- フローティングウィンドウはNeovim 0.4.0以降で利用可能
- 9種類のプリセットレイアウト（left、right、up、down、center等）を提供
- InvisibleEndOfBufferハイライトでバッファ末尾の表示を最適化

---

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

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

### 推奨読解順序

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

本機能はグローバル辞書`g:spacevim#api#nvim#floating_win`としてAPIを提供。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | nvim.vim | `core/autoload/spacevim/api/nvim.vim` | APIオブジェクトの構造 |

**読解のコツ**: Vim scriptでは辞書（Dictionary）にメソッドを持たせることでオブジェクト指向的なパターンを実現。`self`は辞書自身を参照。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nvim.vim | `core/autoload/spacevim/api/nvim.vim` | open関数が基本のエントリーポイント |

**主要処理フロー**:
1. **1行目**: `let g:spacevim#api#nvim#floating_win = {}` - APIオブジェクト初期化
2. **3-27行目**: `open(row, col, width, height)` - 基本のウィンドウ作成関数
3. **12行目**: `nvim_create_buf(v:false, v:true)` - バッファ作成
4. **13行目**: `nvim_open_win(buf, v:true, opts)` - ウィンドウ作成
5. **15-16行目**: ハイライト設定

#### Step 3: レイアウトメソッドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nvim.vim | `core/autoload/spacevim/api/nvim.vim` | 各レイアウトメソッドの実装 |

**主要処理フロー**:
- **34-41行目**: `left()` - 左半分に配置
- **48-59行目**: `right()` - 右半分に配置（ステータスライン考慮）
- **66-73行目**: `up()` - 上半分に配置
- **80-87行目**: `down()` - 下半分に配置
- **95-102行目**: `upLeft()` - 左上に配置
- **109-116行目**: `downLeft()` - 左下に配置
- **124-131行目**: `downRight()` - 右下に配置
- **138-145行目**: `upRight()` - 右上に配置
- **153-160行目**: `center()` - 中央に配置（2/3サイズ）
- **162-169行目**: `upCenter()` - 上部中央に配置

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

```
呼び出し元（プラグイン等）
    │
    └─ g:spacevim#api#nvim#floating_win.center()
           │
           ├─ サイズ計算
           │      └─ width = &columns * 2 / 3
           │      └─ height = &lines * 2 / 3
           │
           └─ self.open(row, col, width, height)
                  │
                  ├─ nvim_create_buf(v:false, v:true)
                  │      └─ スクラッチバッファ作成
                  │
                  ├─ nvim_open_win(buf, v:true, opts)
                  │      └─ フローティングウィンドウ表示
                  │
                  └─ setwinvar / setlocal
                         └─ ハイライト・オプション設定
```

### データフロー図

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

&columns, &lines    位置・サイズ計算              フローティング
&laststatus     ──▶                          ──▶  ウィンドウ
&cmdheight             │
                       ▼
                 nvim_create_buf
                       │
                       ▼
                 nvim_open_win
                       │
                       ▼
                 setwinvar/setlocal
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nvim.vim | `core/autoload/spacevim/api/nvim.vim` | ソース | フローティングウィンドウAPI |
