# 画面設計書 12-差分エディタ

## 概要

本ドキュメントは、Visual Studio Codeの差分エディタ画面の設計を記載したものである。差分エディタは2つのファイル/バージョン間の変更を視覚的に比較・表示する機能を提供する。

### 本画面の処理概要

差分エディタ（DiffEditor）は、2つのテキストコンテンツを並べて表示し、その差分を視覚的にハイライト表示する画面である。左側に変更前（オリジナル）、右側に変更後（修正版）を表示する「サイドバイサイド」表示と、1つのエディタ内で差分を表示する「インライン」表示の2つのモードをサポートする。

**業務上の目的・背景**：
開発者がコードの変更内容を効率的にレビューし、理解するための重要な機能である。Gitの変更確認、ファイル比較、マージコンフリクトの解決など、様々なシナリオで使用される。変更箇所を明確に可視化することで、コードレビューの品質向上とバグの早期発見に貢献する。

**画面へのアクセス方法**：
- ソース管理パネルで変更ファイルをクリック
- ファイルを右クリック→「選択項目と比較」
- ローカル履歴から以前のバージョンと比較
- コマンドパレット「ファイルの比較」を実行
- Git: 作業ツリーの変更を表示

**主要な操作・処理内容**：
1. 2つのファイル/バージョンの差分表示
2. 変更箇所のハイライト表示（追加は緑、削除は赤）
3. 変更箇所間のナビゲーション（前/次の変更へ移動）
4. サイドバイサイド表示とインライン表示の切り替え
5. 差分のマージ（変更の取り込み/却下）
6. スクロールの同期（両エディタが連動してスクロール）

**画面遷移**：
- 入力元: ソース管理ビュー、エクスプローラー（比較操作）、ローカル履歴、テキストエディタ
- 出力先: テキストエディタ（変更を受け入れた場合）

**権限による表示制御**：
- 読み取り専用ファイルの場合、修正側エディタも読み取り専用となる
- ワークスペース信頼設定により制限される場合がある

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | 差分表示 | 主機能 | 2つのファイル間の差分を視覚的に表示 |
| 2 | サイドバイサイド比較 | 主機能 | 左右に並べて差分を表示 |
| 3 | インライン比較 | 主機能 | 1つのエディタ内で差分を表示 |
| 4 | 差分ナビゲーション | 補助機能 | 前/次の変更箇所への移動 |
| 5 | 変更のマージ | 補助機能 | 差分の取り込み/却下 |
| 6 | スクロール同期 | 補助機能 | 左右エディタの連動スクロール |
| 7 | 差分アルゴリズム切り替え | 補助機能 | レガシー/高度な差分アルゴリズムの選択 |
| 8 | 空白無視 | 補助機能 | 空白の変更を無視して比較 |

## 画面種別

編集画面（比較表示）

## URL/ルーティング

内部ルーティング: エディタタブシステムによる管理
識別子: `workbench.editor.textDiffEditor`

## 入出力項目

| 項目名 | 型 | 必須 | 入力/出力 | 説明 |
|--------|-----|------|----------|------|
| original | URI | 必須 | 入力 | 比較元（オリジナル）ファイルのURI |
| modified | URI | 必須 | 入力 | 比較先（修正版）ファイルのURI |
| options | ITextDiffEditorOptions | 任意 | 入力 | 差分エディタオプション |
| label | string | 任意 | 入力 | エディタタブに表示するラベル |

## 表示項目

| 項目名 | 説明 | データソース |
|--------|------|-------------|
| オリジナルエディタ | 変更前のコンテンツ（左側） | オリジナルファイル |
| 修正エディタ | 変更後のコンテンツ（右側） | 修正ファイル |
| 差分デコレーション | 追加/削除/変更の視覚的ハイライト | 差分アルゴリズム |
| 差分オーバービュー | 右端の差分位置インジケーター | 差分アルゴリズム |
| ナビゲーションボタン | 前/次の変更へ移動ボタン | UI |

## イベント仕様

### 1-差分計算

ファイルが読み込まれると差分計算が実行される。

- トリガー: setInput呼び出し時
- 処理: DiffComputerによる差分算出
- 結果: 差分デコレーションの表示

### 2-差分ナビゲーション

変更箇所間を移動する。

- トリガー: F7（次の変更）、Shift+F7（前の変更）、ボタンクリック
- 処理: DiffNavigatorによる移動処理
- 結果: 該当する差分箇所へスクロール

### 3-表示モード切り替え

サイドバイサイド表示とインライン表示を切り替える。

- トリガー: ツールバーボタン、設定変更
- 処理: renderSideBySideオプションの変更
- 結果: レイアウトの再構築

### 4-変更の取り込み

差分の変更をマージする。

- トリガー: インラインアクションボタンクリック
- 処理: 修正内容をオリジナルに反映
- 結果: ファイルの更新

### 5-スクロール同期

両エディタのスクロールを同期する。

- トリガー: いずれかのエディタのスクロール
- 処理: 差分マッピングに基づく対応位置計算
- 結果: 両エディタが連動してスクロール

## データベース更新仕様

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| 変更の保存 | ファイルシステム | UPDATE | マージした内容をファイルに保存 |
| ビューステート保存 | StorageService | UPDATE | 差分エディタの表示状態を永続化 |

## メッセージ仕様

| メッセージID | 種別 | メッセージ内容 | 表示条件 |
|------------|------|---------------|---------|
| MSG001 | 情報 | "No changes" | 差分がない場合 |
| MSG002 | 情報 | "{0} differences" | 差分数の表示 |

## 例外処理

| 例外 | 条件 | 対応 |
|------|------|------|
| ファイル未検出 | 比較対象ファイルが存在しない | エラーメッセージ表示 |
| バイナリファイル | バイナリファイルの比較試行 | テキスト比較不可の通知 |
| 大規模差分 | 差分が非常に大きい場合 | パフォーマンス警告 |

## 備考

- Monaco DiffEditorを基盤として構築
- Git統合により、ステージング前後の変更比較が可能
- 3方向マージ（3-way merge）もサポート
- 差分アルゴリズムは設定で変更可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | diffEditorInput.ts | `src/vs/workbench/common/editor/diffEditorInput.ts` | IDiffEditorInputなど入力インターフェース確認 |
| 1-2 | diff.ts | `src/vs/editor/common/diff/diff.ts` | IChange, IDiffResultなど差分データ構造 |

**読解のコツ**: 差分計算の入力と出力となるデータ構造を先に把握する。

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | textDiffEditor.ts | `src/vs/workbench/browser/parts/editor/textDiffEditor.ts` | TextDiffEditorクラスがメインクラス |

**主要処理フロー**:
1. **42行目**: TextDiffEditorクラス定義 - AbstractTextEditorを継承
2. **67-78行目**: コンストラクタ - サービス注入と初期化
3. **90-135行目**: createEditorControl - DiffEditorWidgetの生成
4. **140-200行目**: setInput - 差分入力の設定

#### Step 3: 差分計算を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | diffComputer.ts | `src/vs/editor/common/diff/diffComputer.ts` | 差分アルゴリズムの実装 |
| 3-2 | linesDiffComputer.ts | `src/vs/editor/common/diff/linesDiffComputer.ts` | 行ベースの差分計算 |

**主要処理フロー**:
- **101行目**: computeDiff - メイン差分計算メソッド
- **138行目**: _computeDiffNaive - 基本的な差分アルゴリズム

#### Step 4: 差分表示を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | diffEditorWidget.ts | `src/vs/editor/browser/widget/diffEditorWidget.ts` | 差分表示ウィジェット |

**主要処理フロー**:
- **200-250行目**: _renderSideBySide - サイドバイサイド表示
- **300-350行目**: _renderInline - インライン表示
- **400-450行目**: _updateDecorations - 差分デコレーション更新

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

```
TextDiffEditor (textDiffEditor.ts)
    │
    ├─ createEditorControl()
    │      └─ new DiffEditorWidget()
    │             ├─ originalEditor (ICodeEditor)
    │             └─ modifiedEditor (ICodeEditor)
    │
    ├─ setInput()
    │      ├─ resolveInput()
    │      │      ├─ getOriginalInput()
    │      │      └─ getModifiedInput()
    │      └─ updateModel()
    │             └─ DiffComputer.computeDiff()
    │
    └─ DiffNavigator
           ├─ next()
           └─ previous()
```

### データフロー図

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

DiffEditorInput ────────▶ setInput() ──────────────────▶ 差分エディタ表示
  (original URI,               │
   modified URI)               ▼
                    resolveModels()
                              │
                              ▼
                    DiffComputer.computeDiff()
                              │
                              ▼
                    IDiffResult ─────────────────────▶ 差分デコレーション
                              │
                              ▼
                    updateDecorations() ──────────────▶ 視覚的ハイライト
                              │
ナビゲーション操作 ─────────▶ │
                              ▼
                    DiffNavigator.next/prev() ────────▶ スクロール
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| textDiffEditor.ts | `src/vs/workbench/browser/parts/editor/textDiffEditor.ts` | ソース | 差分エディタのメインクラス |
| diffEditorInput.ts | `src/vs/workbench/common/editor/diffEditorInput.ts` | ソース | 差分エディタの入力 |
| diffEditorWidget.ts | `src/vs/editor/browser/widget/diffEditorWidget.ts` | ソース | Monaco差分ウィジェット |
| diffComputer.ts | `src/vs/editor/common/diff/diffComputer.ts` | ソース | 差分計算エンジン |
| linesDiffComputer.ts | `src/vs/editor/common/diff/linesDiffComputer.ts` | ソース | 行ベース差分計算 |
| diff.ts | `src/vs/editor/common/diff/diff.ts` | ソース | 差分データ構造定義 |
| diffNavigator.ts | `src/vs/editor/browser/widget/diffNavigator.ts` | ソース | 差分ナビゲーション |
