# 画面設計書 21-カラー表示（textDocument/documentColor）

## 概要

本ドキュメントは、serve-d LSPサーバーにおける `textDocument/documentColor` および `textDocument/colorPresentation` リクエストの処理仕様を定義する画面設計書である。DML（DlangUI Markup Language）ファイル内のHEXカラーコードを検出し、エディタ上にカラー情報を提供する機能を記述する。

### 本画面の処理概要

**業務上の目的・背景**：DlangUI Markup Language（DML）ファイルを編集する開発者が、ソースコード中に記述されたHEXカラーコード（例: `#ff0000`）を視覚的に確認・編集できるようにするための機能である。LSPプロトコルの `textDocument/documentColor` を通じて、エディタ側でカラーピッカーやカラーデコレーション表示を実現する。DMLファイル以外では動作しないため、D言語の一般的なソースファイルでは無効となる。

**画面へのアクセス方法**：エディタがDMLファイルを開いた際に、LSPクライアントが自動的に `textDocument/documentColor` リクエストをサーバーに送信する。ユーザーが明示的に操作する必要はなく、エディタが対応している場合は自動的にカラーデコレーションが表示される。カラーピッカーで色を変更した場合は `textDocument/colorPresentation` リクエストが送信される。

**主要な操作・処理内容**：
1. DMLファイル内のテキストを正規表現 `#([0-9a-fA-F]{2}){3,4}` でスキャンし、HEXカラーコード（6桁RGB or 8桁ARGB）を検出する
2. 検出された各カラーコードについて、ドキュメント内の位置（TextRange）とRGBA色情報（0.0-1.0）を `ColorInformation` として返却する
3. カラーピッカーで色が選択された場合、`textDocument/colorPresentation` により選択色をHEXカラーコード文字列に変換して返却する

**画面遷移**：本機能は独立した情報提供機能であり、他の画面への遷移は発生しない。エディタがDMLファイルを開いている間、継続的にカラー情報を提供する。

**権限による表示制御**：権限による表示制御は存在しない。DMLファイルであれば一律にカラー検出が実行される。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 33 | ドキュメントカラー (textDocument/documentColor) | 主機能 | DMLファイル内のHEXカラーコードを検出しカラー情報を返却する |
| 34 | カラープレゼンテーション (textDocument/colorPresentation) | 補助機能 | カラーピッカーで選択された色をHEXカラーコード文字列に変換して返却する |

## 画面種別

情報提供（LSPプロトコルレスポンス）

## URL/ルーティング

- LSPメソッド: `textDocument/documentColor`
- LSPメソッド: `textDocument/colorPresentation`

## 入出力項目

### textDocument/documentColor

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|-----|----------|------|------|
| params.textDocument.uri | DocumentUri | 入力 | Yes | 対象ドキュメントのURI |
| ColorInformation[] | ColorInformation[] | 出力 | - | 検出されたカラー情報の配列（DMLファイル以外はnull） |
| ColorInformation.range | TextRange | 出力 | - | カラーコードのドキュメント内位置 |
| ColorInformation.color | Color | 出力 | - | RGBA色情報（各値0.0〜1.0） |

### textDocument/colorPresentation

| 項目名 | 型 | 入力/出力 | 必須 | 説明 |
|--------|-----|----------|------|------|
| params.textDocument.uri | DocumentUri | 入力 | Yes | 対象ドキュメントのURI |
| params.color | Color | 入力 | Yes | カラーピッカーで選択された色（RGBA） |
| params.range | TextRange | 入力 | Yes | 置換対象の範囲 |
| ColorPresentation[] | ColorPresentation[] | 出力 | - | HEXカラーコード文字列の配列（要素数1） |

## 表示項目

| 項目名 | 表示形式 | 説明 |
|--------|---------|------|
| カラーデコレーション | カラースウォッチ | エディタ上でHEXカラーコードの隣に色見本が表示される |
| カラーピッカー | ダイアログ | カラーデコレーションをクリックするとカラーピッカーが表示される（エディタ側機能） |

## イベント仕様

### 1-ドキュメントカラー検出

エディタがDMLファイルを開いている際、`textDocument/documentColor` リクエストが送信される。

1. ドキュメントURIから `Document` オブジェクトを取得する
2. 言語IDが `"dml"` でなければ `null` を返却して終了する
3. ドキュメントのテキスト全体を正規表現 `#([0-9a-fA-F]{2}){3,4}` でスキャンする
4. 各マッチに対し、ダブルクォートで囲まれている場合はクォートを除去する
5. 6桁の場合はRGB、8桁の場合はARGBとしてパースする（各チャネル16進数→0.0〜1.0に正規化）
6. テキスト位置を `movePositionBytes` でバイトオフセットから `Position` に変換する
7. `ColorInformation(range, color)` の配列を返却する

### 2-カラープレゼンテーション変換

カラーピッカーで色が変更された際、`textDocument/colorPresentation` リクエストが送信される。

1. ドキュメントURIから `Document` オブジェクトを取得する
2. 言語IDが `"dml"` でなければ `null` を返却して終了する
3. アルファ値が1.0でない場合: `#AARRGGBB` 形式（8桁）のHEXコードに変換する
4. アルファ値が1.0の場合: `#RRGGBB` 形式（6桁）のHEXコードに変換する
5. `ColorPresentation(hex)` を要素数1の配列で返却する

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

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

本機能はデータベースに対する操作を行わない。ドキュメントテキストの読み取りのみを行う読み取り専用の処理である。

## メッセージ仕様

本機能は明示的なメッセージ表示を行わない。カラー情報はLSPプロトコル経由でエディタに返却され、エディタ側でカラーデコレーションとして表示される。

## 例外処理

| 条件 | 挙動 |
|------|------|
| DMLファイル以外のドキュメント | `null` を返却（エラーなし） |
| カラーコードが存在しないDMLファイル | 空の `ColorInformation[]` を返却 |
| 不正な正規表現マッチ（理論上発生しない） | `assert` でアサーションエラー |

## 備考

- HEXカラーコードは `#RRGGBB`（6桁）および `#AARRGGBB`（8桁）の2形式に対応している
- ダブルクォートで囲まれた `"#RRGGBB"` 形式もマッチ対象となる
- 色の各チャネル値は16進数を255で除算して0.0〜1.0の浮動小数点数に変換される
- 本機能はDMLファイル専用であり、D言語ソースファイル（`.d`）やdietテンプレートでは動作しない

---

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

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

### 推奨読解順序

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

LSPプロトコルで定義されたカラー関連のデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | protocol.d | `source/served/lsp/protocol.d` | `Color`, `ColorInformation`, `ColorPresentation`, `DocumentColorParams`, `ColorPresentationParams` の各構造体定義を確認する |

**読解のコツ**: LSPプロトコルの型定義はD言語の構造体として表現されている。`Color` は `red`, `green`, `blue`, `alpha` の4つの `double` フィールドを持つ。

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

2つのLSPメソッドハンドラがエントリーポイントとなる。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | color.d | `source/served/commands/color.d` | `provideDocumentColor` 関数（行12-55）と `provideColorPresentations` 関数（行57-81）が2つのエントリーポイント |

**主要処理フロー**:
1. **行9**: `colorRegex` - HEXカラーコード検出用の正規表現をコンパイル時に定義
2. **行12-55**: `provideDocumentColor` - ドキュメント内のカラーコードを検出
3. **行14-16**: 言語IDが `"dml"` でなければ即座にnull返却
4. **行28**: `matchAll` でテキスト全体を正規表現スキャン
5. **行38-39**: バイトオフセットから `Position` への変換
6. **行42-49**: HEXカラーコードの各チャネルをパース（8桁対応含む）
7. **行57-81**: `provideColorPresentations` - RGBA値からHEXカラーコードへの逆変換

#### Step 3: ドキュメント管理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | textdocumentmanager.d | `source/served/lsp/textdocumentmanager.d` | `documents` オブジェクトによるドキュメント管理、`movePositionBytes` によるバイト位置変換を理解する |

**主要処理フロー**:
- `documents[uri]` でドキュメントテキストを取得
- `getLanguageId` で言語判別
- `movePositionBytes` でバイトオフセットを行・列の `Position` に変換

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

```
textDocument/documentColor リクエスト
    |
    +-- provideDocumentColor (color.d:12)
           |
           +-- documents[uri] (テキスト取得)
           +-- getLanguageId() (DML判定)
           +-- matchAll(rawText, colorRegex) (正規表現マッチ)
           +-- movePositionBytes() (位置変換)

textDocument/colorPresentation リクエスト
    |
    +-- provideColorPresentations (color.d:57)
           |
           +-- documents[uri] (テキスト取得)
           +-- getLanguageId() (DML判定)
           +-- format (HEX文字列生成)
```

### データフロー図

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

DocumentColorParams ---------> provideDocumentColor ----------> ColorInformation[]
  textDocument.uri               |
                                 +-- Document取得
                                 +-- 正規表現マッチ
                                 +-- HEXパース
                                 +-- 位置変換

ColorPresentationParams -----> provideColorPresentations ----> ColorPresentation[]
  color (RGBA)                   |
  textDocument.uri               +-- Document取得
  range                          +-- HEXフォーマット
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| color.d | `source/served/commands/color.d` | ソース | カラー検出・変換の主処理 |
| protocol.d | `source/served/lsp/protocol.d` | ソース | LSPプロトコル型定義（Color, ColorInformation等） |
| types.d | `source/served/types.d` | ソース | 共通型定義・documents等のエイリアス |
| textdocumentmanager.d | `source/served/lsp/textdocumentmanager.d` | ソース | ドキュメント管理、位置変換ユーティリティ |
