# 機能設計書 7-マルチカーソル

## 概要

本ドキュメントは、VS Codeエディタにおけるマルチカーソル機能の設計仕様を記載する。複数箇所への同時入力・編集機能を実現する。

### 本機能の処理概要

マルチカーソル機能は、エディタ内に複数のカーソルを同時に配置し、複数箇所に対して同時に同じ編集操作を適用する機能である。

**業務上の目的・背景**：ソフトウェア開発において、同じパターンの変更を複数箇所に適用する作業は頻繁に発生する。マルチカーソルにより、検索・置換を使用せずに視覚的に確認しながら複数箇所を同時編集でき、作業効率と正確性が大幅に向上する。

**機能の利用シーン**：
- 同じ変数名を複数箇所で同時に変更
- 複数行に同じテキストを追加（コメントアウト等）
- 列選択モードで複数行を同時編集
- 同一単語の出現箇所を選択して一括編集

**主要な処理内容**：
1. カーソル追加 - Ctrl+Alt+上下矢印でカーソルを追加
2. 同一単語選択 - Ctrl+Dで現在位置の単語と同じ単語を順次選択
3. 全出現箇所選択 - Ctrl+Shift+Lで単語の全出現箇所を選択
4. 列選択モード - Alt+Shiftでドラッグで列選択
5. 同時編集実行 - 全カーソル位置に同じ入力を適用

**関連システム・外部連携**：検索機能（FindController）と連携して同一単語の検索を行う。

**権限による制御**：読み取り専用モードではカーソル追加のみ可能、編集は無効。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 11 | テキストエディタ | 主画面 | 複数箇所への同時入力・編集機能 |

## 機能種別

編集処理 / 選択処理 / カーソル操作

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| source | string | No | カーソル追加の発生源 | - |
| logicalLine | boolean | No | 論理行単位でカーソル追加 | true/false |
| selectHighlights | boolean | No | ハイライト箇所を選択 | true/false |

### 入力データソース

- キーボードショートカット（Ctrl+Alt+上下矢印）
- マウス操作（Alt+クリック）
- コマンドパレット

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| cursorStates | CursorState[] | 全カーソルの状態 |
| selections | Selection[] | 全選択範囲 |
| decorations | IModelDeltaDecoration[] | カーソルデコレーション |

### 出力先

- エディタ画面（複数カーソル表示）
- アクセシビリティ通知（カーソル追加アナウンス）

## 処理フロー

### 処理シーケンス

```
1. カーソル追加要求受付
   └─ ショートカットまたはマウス操作を検知
2. ViewModelの状態確認
   └─ 読み取り専用チェック
3. Undoスタックに状態保存
   └─ pushStackElement()で現在状態を保存
4. 新しいカーソル状態計算
   └─ CursorMoveCommands.addCursorUp/Downで計算
5. カーソル状態更新
   └─ setCursorStates()で複数カーソルを設定
6. ビュー更新
   └─ revealTopMost/BottomMostCursor()でスクロール
7. アクセシビリティ通知
   └─ announceCursorChange()でカーソル追加を通知
```

### フローチャート

```mermaid
flowchart TD
    A[カーソル追加要求] --> B{読み取り専用?}
    B -->|Yes| C[処理終了]
    B -->|No| D[pushStackElement]
    D --> E[previousCursorState取得]
    E --> F{追加方向}
    F -->|上| G[addCursorUp]
    F -->|下| H[addCursorDown]
    G --> I[setCursorStates]
    H --> I
    I --> J[revealCursor]
    J --> K[announceCursorChange]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-001 | カーソル数上限 | multiCursorLimitで上限設定（デフォルト10000） | カーソル追加時 |
| BR-002 | 論理行モード | logicalLineで折り返し行を考慮 | カーソル上下追加時 |
| BR-003 | 重複排除 | 同一位置へのカーソル追加は無視 | カーソル追加時 |
| BR-004 | アクセシビリティ | スクリーンリーダー向けにカーソル位置を通知 | カーソル追加後 |

### 計算ロジック

特になし

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

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

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

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| READONLY | 情報 | 読み取り専用モードでの編集試行 | カーソル追加のみ許可、編集は拒否 |
| LIMIT_EXCEEDED | 警告 | カーソル数が上限超過 | 追加を拒否 |

### リトライ仕様

特になし

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

カーソル追加前にpushStackElement()でUndo境界を作成。Undoで全カーソルを追加前の状態に戻せる。

## パフォーマンス要件

- カーソル追加: 即座
- 同時編集: カーソル数に比例した処理時間

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

特になし

## 備考

マルチカーソル機能はSublime Textから普及した編集パラダイムで、VS Codeでも主要機能の一つ。

---

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

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

### 推奨読解順序

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

まず、カーソル状態のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cursorCommon.ts | `src/vs/editor/common/cursorCommon.ts` | CursorState |
| 1-2 | selection.ts | `src/vs/editor/common/core/selection.ts` | Selection |

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

アクションクラスを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | multicursor.ts | `src/vs/editor/contrib/multicursor/browser/multicursor.ts` | InsertCursorAbove, InsertCursorBelow |

**主要処理フロー**:
1. **46-96行目**: InsertCursorAbove - 上方向にカーソル追加
2. **98-148行目**: InsertCursorBelow - 下方向にカーソル追加
3. **32-39行目**: announceCursorChange() - アクセシビリティ通知
4. **71-95行目**: run() - CursorMoveCommands.addCursorUp呼び出し

#### Step 3: カーソル操作を理解する

カーソル移動コマンドの実装を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | cursorMoveCommands.ts | `src/vs/editor/common/cursor/cursorMoveCommands.ts` | addCursorUp, addCursorDown |

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

```
InsertCursorAbove/Below.run()
    │
    ├─ viewModel.cursorConfig.readOnly確認
    │
    ├─ viewModel.model.pushStackElement()
    │
    ├─ CursorMoveCommands.addCursorUp/Down()
    │      └─ 新しいCursorState[]を計算
    │
    ├─ viewModel.setCursorStates()
    │
    ├─ viewModel.revealTopMost/BottomMostCursor()
    │
    └─ announceCursorChange()
           └─ status() - アクセシビリティ通知
```

### データフロー図

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

ショートカット ──▶ InsertCursorAbove/Below ──▶ 新しいカーソル追加
                        │
                        ▼
CursorState[] ──▶ CursorMoveCommands ──▶ 新しいCursorState[]
                        │
                        ▼
setCursorStates() ──▶ ViewModel更新 ──▶ 画面表示更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| multicursor.ts | `src/vs/editor/contrib/multicursor/browser/multicursor.ts` | ソース | マルチカーソルアクション |
| cursorMoveCommands.ts | `src/vs/editor/common/cursor/cursorMoveCommands.ts` | ソース | カーソル移動コマンド |
| cursorCommon.ts | `src/vs/editor/common/cursorCommon.ts` | ソース | カーソル共通定義 |
| selection.ts | `src/vs/editor/common/core/selection.ts` | ソース | 選択範囲データ構造 |
