# 機能設計書 43-Vim エミュレーション

## 概要

本ドキュメントは、Doom EmacsにおけるVimエミュレーション機能の設計仕様を記述する。evil-modeを基盤として、Vimのモーダル編集、テキストオブジェクト、オペレータ、マクロ、Exコマンドなどを完全にエミュレートし、EmacsをVimユーザーにとって馴染みやすい環境に変換する。

### 本機能の処理概要

**業務上の目的・背景**：Vimは効率的なテキスト編集を可能にするモーダルエディタとして広く使われている。多くの開発者がVimのキーバインドに習熟しており、Emacsの強力な拡張性とVimの効率的な編集操作を組み合わせることで、両方の利点を享受できる。本機能により、VimユーザーがEmacsの学習コストを最小限に抑えながら、Emacsエコシステムの恩恵を受けられる。

**機能の利用シーン**：
- テキストファイルやコードの効率的な編集
- Vimスタイルのナビゲーション（hjkl移動）
- テキストオブジェクトを使った高度な選択・編集
- マクロ記録・再生による繰り返し作業の自動化
- Exコマンドによるファイル操作、検索・置換

**主要な処理内容**：
1. モーダル編集（Normal/Insert/Visual/Operator-pending等のステート管理）
2. Vimキーバインドの提供（移動、編集、削除、ヤンク等）
3. テキストオブジェクト（word, WORD, paragraph, block等）
4. オペレータ（delete, change, yank等）とモーションの組み合わせ
5. ビジュアル選択（文字、行、ブロック）
6. マクロ記録・再生
7. Exコマンドラインインターフェース
8. サラウンド編集（evil-surround）
9. スナイプ移動（evil-snipe）
10. イージーモーション（evil-easymotion）
11. コメント操作（evil-nerd-commenter）

**関連システム・外部連携**：
- evil: Vimエミュレーションの基盤
- evil-collection: 多くのモードへのEvil統合
- evil-surround: サラウンド編集
- evil-snipe: 2文字検索
- evil-easymotion: モーション強化
- evil-nerd-commenter: コメント操作
- evil-escape: インサートモードからの高速脱出
- evil-exchange: テキスト交換
- evil-lion: アライメント
- evil-numbers: 数値増減
- evil-visualstar: ビジュアル選択での検索

**権限による制御**：特になし（全ユーザーが利用可能）

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 2 | Treemacs | 補助機能 | treemacs-evil連携、Vim風キーバインド |
| 4 | Vertico | 補助機能 | Evil対応キーバインド（C-j/C-k移動） |

## 機能種別

テキスト編集 / UI制御 / キーバインド管理

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| evil-want-keybinding | boolean | No | evil-collectionの自動キーバインド | - |
| evil-want-C-u-scroll | boolean | No | C-uでスクロール | - |
| evil-want-Y-yank-to-eol | boolean | No | Yで行末までヤンク | - |
| +evil-want-o/O-to-continue-comments | boolean | No | o/Oでコメント継続 | - |

### 入力データソース

- キーボード入力（キーシーケンス）
- Exコマンドライン入力
- マウス操作（サポート範囲内）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| evil-state | symbol | 現在のEvilステート |
| evil-mode-line-tag | string | モードライン表示用タグ |
| kill-ring | list | ヤンク・削除されたテキスト |
| evil-registers | alist | Vimレジスタの内容 |

### 出力先

- バッファ（テキスト編集結果）
- キルリング/レジスタ（テキスト保存）
- ミニバッファ（Exコマンド、検索）
- モードライン（ステート表示）

## 処理フロー

### 処理シーケンス

```
1. キー入力受付
   └─ evil-read-keyでキーシーケンス取得
2. ステート判定
   └─ 現在のevil-stateに基づきキーマップ選択
3. コマンド解決
   └─ キーシーケンスからコマンドを解決
4. オペレータ/モーション処理
   ├─ オペレータの場合: オペレーティングペンディングステートへ
   └─ モーションの場合: 範囲計算→オペレータ適用
5. ステート遷移
   └─ コマンド実行結果に基づきステート変更
```

### フローチャート

```mermaid
flowchart TD
    A[キー入力] --> B{現在のステート}
    B -->|Normal| C[Normal State Keymap]
    B -->|Insert| D[Insert State Keymap]
    B -->|Visual| E[Visual State Keymap]
    B -->|Operator-pending| F[Motion待ち]

    C --> G{コマンド種別}
    G -->|オペレータ| H[Operator-pending State]
    G -->|モーション| I[カーソル移動]
    G -->|その他| J[コマンド実行]

    H --> K[モーション入力待ち]
    K --> L[範囲計算]
    L --> M[オペレータ適用]
    M --> N[Normal Stateへ]

    D --> O{キー}
    O -->|ESC/C-g| N
    O -->|通常文字| P[文字挿入]
    P --> D

    E --> Q{コマンド}
    Q -->|オペレータ| R[選択範囲に適用]
    R --> N
    Q -->|モーション| S[選択範囲拡張]
    S --> E
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | モーダル編集 | Normal/Insert/Visual/Emacs等のステートを維持 | 常時 |
| BR-02 | カーソル形状 | ステートごとに異なるカーソル形状（box/bar/hollow） | 常時 |
| BR-03 | レジスタ永続性 | 数字レジスタ(2-9)はグローバル | 常時 |
| BR-04 | ヤンク選択非コピー | ビジュアル選択をクリップボードにコピーしない | evil-visual-update-x-selection-p = nil |
| BR-05 | マクロエラー抑制 | 行頭/行末エラーでマクロを中断しない | 常時 |

### 計算ロジック

カーソル色設定:
```elisp
(defun +evil-default-cursor-fn ()
  (evil-set-cursor-color (get 'cursor 'evil-normal-color)))
(defun +evil-emacs-cursor-fn ()
  (evil-set-cursor-color (get 'cursor 'evil-emacs-color)))
```

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

本機能はデータベースを使用しない。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | user-error | 無効なモーション | エラーメッセージ表示 |
| - | error | マクロ実行中のエラー | マクロ中断（抑制設定可） |
| - | user-error | レジスタ未定義 | エラーメッセージ表示 |

### リトライ仕様

マクロ実行中のモーションエラーは`evil-kbd-macro-suppress-motion-error`により抑制可能。

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

トランザクション処理は不要。undo機能はEmacs標準またはundo-fu/undo-treeと連携。

## パフォーマンス要件

- キー入力応答: 即座
- マクロ再生: 編集内容に依存
- 検索ハイライト: 選択ウィンドウのみに制限（パフォーマンス最適化）

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

特になし。

## 備考

- `+everywhere`フラグでevil-collectionによる広範なモード統合を有効化
- カスタムテキストオブジェクトの追加が可能
- Exコマンドのカスタム定義が可能

---

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

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

### 推奨読解順序

#### Step 1: 基本設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/editor/evil/config.el` | evil基本設定、変数定義 |

**読解のコツ**:
- **3-25行目**: カスタム変数定義（+evil-want-o/O-to-continue-comments等）
- **17-25行目**: evil初期化前の設定（defvar）
- **27-211行目**: evil本体の設定（use-package!ブロック）

#### Step 2: カーソル・UI設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | config.el | `modules/editor/evil/config.el` | カーソル形状、色設定 |

**主要処理フロー**:
- **38-42行目**: ステートごとのカーソル形状定義
- **100-110行目**: カーソル色の動的設定
- **107-110行目**: カーソル色変更関数

#### Step 3: Exコマンドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | +commands.el | `modules/editor/evil/+commands.el` | Exコマンド定義 |

**主要処理フロー**:
- **6-17行目**: 編集系コマンド（align, retab等）
- **33-42行目**: Git連携コマンド
- **44-52行目**: バッファ操作コマンド
- **88-101行目**: ワークスペース/タブ連携コマンド

#### Step 4: キーバインドを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | config.el | `modules/editor/evil/config.el` | map!マクロによるキーバインド |

**主要処理フロー**:
- **445-654行目**: キーバインド定義（map!ブロック）
- **588-598行目**: テキストオブジェクト定義
- **600-619行目**: evil-easymotion設定

#### Step 5: サブパッケージを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | config.el | `modules/editor/evil/config.el` | サブパッケージ設定 |

**主要処理フロー**:
- **263-288行目**: evil-easymotion
- **290-339行目**: evil-embrace
- **342-359行目**: evil-escape
- **383-391行目**: evil-snipe
- **394-399行目**: evil-surround

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

```
キー入力
    │
    ├─ evil-state判定
    │      └─ evil-normal-state / evil-insert-state / etc.
    │
    ├─ キーマップ解決
    │      ├─ evil-normal-state-map
    │      ├─ evil-insert-state-map
    │      ├─ evil-visual-state-map
    │      └─ evil-motion-state-map
    │
    └─ コマンド実行
           │
           ├─ オペレータ (evil-delete, evil-change, etc.)
           │      └─ モーション待ち → 範囲計算 → 適用
           │
           ├─ モーション (evil-forward-word, evil-next-line, etc.)
           │
           └─ その他 (evil-ex, evil-search, etc.)
                  └─ Exコマンド解析・実行
```

### データフロー図

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

キー入力              ┌──────────────────────┐
     ───────────────▶│ evil-state判定       │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │ キーマップ解決        │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │ コマンド実行          │ ───▶ バッファ変更
                      │ (オペレータ/モーション) │       キルリング
                      └──────────────────────┘       レジスタ
                               │
                               ▼
                      ┌──────────────────────┐
                      │ ステート遷移          │ ───▶ カーソル形状変更
                      └──────────────────────┘       モードライン更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/editor/evil/config.el` | ソース | evil本体・サブパッケージ設定 |
| +commands.el | `modules/editor/evil/+commands.el` | ソース | Exコマンド定義 |
| packages.el | `modules/editor/evil/packages.el` | 設定 | 依存パッケージ定義 |
| evil.el | `modules/editor/evil/autoload/evil.el` | ソース | ユーティリティ関数 |
| advice.el | `modules/editor/evil/autoload/advice.el` | ソース | アドバイス関数 |
| embrace.el | `modules/editor/evil/autoload/embrace.el` | ソース | evil-embrace拡張 |
| textobjects.el | `modules/editor/evil/autoload/textobjects.el` | ソース | カスタムテキストオブジェクト |
| unimpaired.el | `modules/editor/evil/autoload/unimpaired.el` | ソース | vim-unimpaired風コマンド |
| files.el | `modules/editor/evil/autoload/files.el` | ソース | ファイル操作コマンド |
| ex.el | `modules/editor/evil/autoload/ex.el` | ソース | Exコマンドヘルパー |
| test-evil.el | `modules/editor/evil/test/test-evil.el` | テスト | ユニットテスト |
