# 機能設計書 47-マルチカーソル編集

## 概要

本ドキュメントは、Doom Emacsにおけるマルチカーソル編集機能の設計仕様を記述する。evil-mcおよびevil-multieditを基盤として、複数の位置で同時にテキスト編集を行う機能を提供する。

### 本機能の処理概要

**業務上の目的・背景**：コード編集において、同じパターンの複数箇所を同時に編集したいケースは頻繁に発生する（変数名のリネーム、複数行への同一文字列挿入等）。本機能は、複数のカーソルを同時に操作することで、反復的な編集作業を効率化し、開発者の生産性を向上させる。

**機能の利用シーン**：
- 変数名の一括リネーム
- 複数行への同一文字列挿入
- パターンにマッチする全箇所の同時編集
- 矩形選択（ブロック選択）での編集

**主要な処理内容**：
1. パターンマッチによるカーソル作成（:mc コマンド）
2. 次/前のマッチ位置へのカーソル追加
3. ビジュアルブロック選択でのカーソル作成
4. 全カーソルでの同期編集
5. カーソルの一時停止・再開

**関連システム・外部連携**：
- evil-mc: Evilベースのマルチカーソル
- evil-multiedit: マッチベースのマルチ編集
- multiple-cursors: Emacsネイティブのマルチカーソル（互換レイヤー）
- iedit: インラインマルチ編集

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

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 画面関連なし（エディタ機能） |

## 機能種別

テキスト編集 / マルチカーソル

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| pattern | string | No | マッチパターン（:mcコマンド用） | 有効な正規表現 |
| beg | integer | No | 範囲開始位置 | バッファ内位置 |
| end | integer | No | 範囲終了位置 | バッファ内位置 |
| flags | symbol | No | マッチフラグ（g: グローバル, i: 大文字小文字無視） | g, i, I |

### 入力データソース

- キーボード入力（C-n, C-p等）
- Exコマンド入力（:mc）
- ビジュアル選択

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| evil-mc-cursor-list | list | アクティブなカーソルのリスト |
| evil-mc-frozen | boolean | カーソルの一時停止状態 |

### 出力先

- バッファ（カーソル表示、編集結果）
- エコーエリア（カーソル数等の情報）

## 処理フロー

### 処理シーケンス

```
1. カーソル作成コマンド
   ├─ パターンマッチ: :mc /pattern/
   ├─ 次のマッチ: C-n / evil-mc-make-and-goto-next-cursor
   └─ ブロック選択: +multiple-cursors/evil-mc-toggle-cursor-here
2. カーソル配置
   └─ 各マッチ位置にカーソルオブジェクト作成
3. 編集モード
   ├─ Insert State進入でカーソル再開
   └─ 全カーソルで同期編集
4. カーソル解除
   └─ ESCまたは明示的なundo-all-cursors
```

### フローチャート

```mermaid
flowchart TD
    A[マルチカーソル開始] --> B{作成方法}
    B -->|:mc pattern| C[パターンマッチ]
    B -->|C-n| D[次のマッチに追加]
    B -->|ブロック選択| E[各行にカーソル]

    C --> F[全マッチ位置にカーソル作成]
    D --> G[現在位置にカーソル + 次へ移動]
    E --> H[選択範囲の各行にカーソル]

    F --> I[evil-mc-cursor-list更新]
    G --> I
    H --> I

    I --> J{Insert State?}
    J -->|Yes| K[カーソル再開]
    J -->|No| L[カーソル一時停止]

    K --> M[同期編集]
    M --> N{ESC?}
    N -->|Yes| O[カーソル解除]
    N -->|No| M
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | Insert時再開 | Insert State進入時にカーソルを自動的に再開 | 常時 |
| BR-02 | ESCで解除 | doom-escape-hookでカーソルを解除 | 常時 |
| BR-03 | 非互換モード無効化 | evil-escape-mode, lispy-modeは一時的に無効化 | マルチカーソルアクティブ時 |
| BR-04 | プレフィックス引数対応 | 数値プレフィックスで繰り返し実行 | 対応コマンド |

### 計算ロジック

カーソル作成（パターンマッチ）:
```elisp
(evil-with-restriction beg end
  (goto-char beg)
  (while (eq (evil-ex-find-next m 'forward t) t)
    (evil-mc-make-cursor-at-pos (1- (point)))
    (unless (evil-ex-pattern-whole-line m)
      (goto-char (line-beginning-position 2)))))
```

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | user-error | パターンが空 | エラーメッセージ表示 |
| - | message | カーソルが作成されなかった | 情報メッセージ表示 |

### リトライ仕様

リトライ処理は実装されていない。

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

トランザクション処理は不要。undo機能で編集を取り消し可能。

## パフォーマンス要件

- カーソル作成: 即座
- 同期編集: カーソル数に比例（多数のカーソルで遅延の可能性）
- バーカーソル描画: Linuxのみ有効（macOS/Windowsでは無効）

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

特になし。

## 備考

- `evil-mc-enable-bar-cursor`はLinuxのみ有効（パフォーマンス上の理由）
- smartparensとの連携のため、カーソル変数を共有
- multiple-cursorsとの互換レイヤーあり（Evilユーザー向け）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | config.el | `modules/editor/multiple-cursors/config.el` | evil-mc設定 |

**読解のコツ**:
- **3-7行目**: 変数定義（+multiple-cursors-evil-mc-ex-global等）
- **26-160行目**: evil-mc設定（use-package!ブロック）
- **163-224行目**: multiple-cursors互換レイヤー

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | evil-mc.el | `modules/editor/multiple-cursors/autoload/evil-mc.el` | コマンド定義 |

**主要処理フロー**:
- **5-14行目**: `+multiple-cursors/evil-mc-toggle-cursors`
- **17-59行目**: `+multiple-cursors/evil-mc-toggle-cursor-here`
- **62-103行目**: `+multiple-cursors:evil-mc`（Exコマンド）

#### Step 3: Evilフック・互換設定を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | config.el | `modules/editor/multiple-cursors/config.el` | フック設定 |

**主要処理フロー**:
- **133行目**: `evil-insert-state-entry-hook`でカーソル再開
- **142-148行目**: `doom-escape-hook`でカーソル解除
- **135-140行目**: 非互換モードリスト

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

```
+multiple-cursors:evil-mc (Exコマンド :mc)
    │
    ├─ evil-ex-make-pattern
    │      └─ パターン解析
    │
    ├─ evil-mc-run-cursors-before
    │
    ├─ evil-mc-make-cursor-at-pos
    │      └─ カーソルオブジェクト作成
    │
    └─ evil-mc-goto-cursor
           └─ 最終カーソル位置へ移動

+multiple-cursors/evil-mc-toggle-cursor-here
    │
    ├─ evil-visual-state-p チェック
    │      └─ evil-apply-on-block
    │             └─ 各行にカーソル作成
    │
    └─ evil-mc-make-cursor-here
           └─ 現在位置にカーソル作成
```

### データフロー図

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

:mc /pattern/         ┌──────────────────────┐
      ───────────────▶│ パターン解析          │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
                      │ マッチ検索            │
                      └──────────────────────┘
                               │
                               ▼
                      ┌──────────────────────┐
マッチ位置に    ◀──── │ カーソル作成          │
カーソル表示          └──────────────────────┘
                               │
                               ▼
Insert State          ┌──────────────────────┐
      ───────────────▶│ 同期編集              │ ───▶ 全カーソル位置で
                      └──────────────────────┘       同一編集
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| config.el | `modules/editor/multiple-cursors/config.el` | ソース | モジュール設定、evil-mc/multiple-cursors設定 |
| evil-mc.el | `modules/editor/multiple-cursors/autoload/evil-mc.el` | ソース | evil-mcコマンド定義 |
| packages.el | `modules/editor/multiple-cursors/packages.el` | 設定 | 依存パッケージ（evil-mc, evil-multiedit, iedit） |
