# 機能設計書 88-カーソル情報

## 概要

本ドキュメントは、clojure-lspのカーソル情報取得機能の設計書である。カーソル位置にある要素の詳細な解析情報を取得する開発者向け機能である。

### 本機能の処理概要

この機能は、LSPプロトコルのカスタム拡張として、エディタのカーソル位置にあるシンボルや式の詳細な解析情報を取得する。デバッグやclojure-lspの動作理解に有用な情報を提供する。

**業務上の目的・背景**：clojure-lspの解析動作を理解したり、特定の位置での解析結果を確認したりする際に、カーソル位置の詳細情報が必要となる。本機能により、シンボルの解析結果、定義情報、セマンティックトークン情報などを取得し、問題の診断や動作理解を支援する。

**機能の利用シーン**：
- clojure-lspの解析結果の確認
- シンボル解析の動作確認
- セマンティックトークンのデバッグ
- 解析問題のトラブルシューティング

**主要な処理内容**：
1. カーソル位置の受信
2. 位置にある要素の検索
3. 関連情報の収集（定義、セマンティックトークンなど）
4. クライアントへの応答

**関連システム・外部連携**：
- LSPクライアント: 情報表示
- clj-kondo: 解析データ

**権限による制御**：権限による制御は行わない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 該当なし | 該当なし | 該当なし | エディタのコマンドパレットから実行（LSP拡張機能） |

## 機能種別

情報取得 / カスタムLSP拡張

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| text-document.uri | String | Yes | ドキュメントのURI | 有効なファイルURI |
| position.line | Integer | Yes | 行番号（0ベース） | 0以上 |
| position.character | Integer | Yes | 文字位置（0ベース） | 0以上 |

### 入力データソース

- clj-kondo解析結果
- rewrite-clj パーサー結果

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| node | Map | カーソル位置のAST ノード情報 |
| node.children-count | Integer | 子ノード数（children がある場合） |
| elements | Vector | カーソル位置にある要素のリスト |
| elements[].element | Map | 要素の詳細情報 |
| elements[].definition | Map | 要素の定義情報（存在する場合） |
| elements[].semantic-tokens | Keyword | セマンティックトークンタイプ |

### 出力形式

2つの出力形式が提供される:
1. **raw**: JSONレスポンスとして構造化データを返却
2. **log**: メッセージウィンドウにpretty-print形式で表示

### 出力先

- **raw**: LSPレスポンス（JSON形式）
- **log**: クライアントのメッセージウィンドウ（window/showMessage）

## 処理フロー

### 処理シーケンス

```
1. リクエスト受信
   └─ clojure/cursorInfo/raw または clojure/cursorInfo/log

2. 位置情報の変換
   └─ 0ベースから1ベースへ変換

3. 要素検索
   └─ find-all-elements-under-cursor

4. ノード情報取得
   └─ zloc から AST ノードを取得

5. 追加情報収集
   └─ 定義情報、セマンティックトークン

6. レスポンス返却
   └─ raw: 構造化データ、log: showMessage通知
```

### フローチャート

```mermaid
flowchart TD
    A[リクエスト受信] --> B[位置情報変換]
    B --> C[find-all-elements-under-cursor]
    C --> D[zloc からノード取得]
    D --> E{要素あり?}
    E -->|Yes| F[各要素に対して]
    E -->|No| G[空のレスポンス]
    F --> H[find-definition]
    H --> I[element->token-type]
    I --> J[要素情報をマップ]
    J --> K{出力タイプ}
    G --> K
    K -->|raw| L[preserve-kebab-case 変換]
    K -->|log| M[pprint 形式に変換]
    L --> N[JSONレスポンス返却]
    M --> O[showMessage 通知]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-88-1 | 位置変換 | クライアントからの0ベース位置を1ベースに変換 | 常時 |
| BR-88-2 | children圧縮 | ノードの children は count のみ出力 | children がある場合 |
| BR-88-3 | 複数要素 | 同一位置に複数の要素が存在する場合はすべて返却 | find-all-elements-under-cursor |

### 計算ロジック

要素情報の構成:
1. element: clj-kondo解析結果の要素データ
2. definition: q/find-definition で取得した定義情報
3. semantic-tokens: f.semantic-tokens/element->token-type で取得

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

該当なし（ファイルシステムのみ操作）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | 要素なし | カーソル位置に要素がない | 空の elements リストを返却 |

### リトライ仕様

リトライは不要。

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

該当なし（読み取り専用処理）

## パフォーマンス要件

- 即座に応答可能（ミリ秒単位）
- 単一位置の検索のため軽量

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

- 読み取り専用操作のためセキュリティリスクは低い

## 備考

- この機能はLSPの実験的（experimental）機能として提供される
- cursor-info コマンドとしてエディタから呼び出し可能

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | cursor-info 出力 | `lib/src/clojure_lsp/feature/development_info.clj` | 出力データの構造 |

**読解のコツ**: cursor-info 関数が返すマップの :node と :elements が主要な出力

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | server.clj | `cli/src/clojure_lsp/server.clj` | LSPリクエストハンドラの登録 |

**主要処理フロー**:
1. **224-228行目**: `clojure/cursorInfo/raw` メソッドの登録
2. **230-236行目**: `clojure/cursorInfo/log` メソッドの登録

#### Step 3: ハンドラ層を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | handlers.clj | `lib/src/clojure_lsp/handlers.clj` | cursor-info-log, cursor-info-raw 関数 |

**主要処理フロー**:
- **357-360行目**: `cursor-info-log` 関数
- **362-365行目**: `cursor-info-raw` 関数
- **360行目, 365行目**: 位置を1ベースに変換（inc）

#### Step 4: 機能実装を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | development_info.clj | `lib/src/clojure_lsp/feature/development_info.clj` | cursor-info の詳細実装 |

**主要処理フロー**:
- **41-56行目**: `cursor-info` 関数 - カーソル情報の収集
- **42行目**: `q/find-all-elements-under-cursor` で要素取得
- **43-45行目**: zloc からノード取得
- **51-55行目**: 各要素の定義とセマンティックトークンを取得

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

```
jsonrpc.server/receive-request "clojure/cursorInfo/raw"
    │
    └─ handler/cursor-info-raw
           │
           └─ f.development-info/cursor-info-raw
                  │
                  └─ cursor-info
                         │
                         ├─ q/find-all-elements-under-cursor
                         ├─ parser/safe-zloc-of-file
                         ├─ parser/to-pos
                         └─ (for each element)
                                ├─ q/find-definition
                                └─ f.semantic-tokens/element->token-type

jsonrpc.server/receive-notification "clojure/cursorInfo/log"
    │
    └─ handler/cursor-info-log
           │
           └─ f.development-info/cursor-info-log
                  │
                  ├─ cursor-info
                  │
                  └─ producer/show-message (pprint)
```

### データフロー図

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

URI + 位置 ─────────▶ 位置変換（0→1ベース）
                              │
                              ▼
                       find-all-elements-under-cursor
                              │
                              ▼
                       zloc → node 取得
                              │
                              ├─ children → children-count
                              │
                              ▼
                       各要素に対して:
                              ├─ find-definition
                              └─ element->token-type
                              │
                              ▼
                       情報マップ構築 ──────▶ {:node ... :elements [...]}
                              │
                              ▼
                       raw/log 分岐 ──────▶ JSONレスポンス / showMessage
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| development_info.clj | `lib/src/clojure_lsp/feature/development_info.clj` | ソース | カーソル情報収集 |
| handlers.clj | `lib/src/clojure_lsp/handlers.clj` | ソース | LSPハンドラー |
| server.clj | `cli/src/clojure_lsp/server.clj` | ソース | LSPサーバー |
| queries.clj | `lib/src/clojure_lsp/queries.clj` | ソース | 要素検索 |
| parser.clj | `lib/src/clojure_lsp/parser.clj` | ソース | AST解析 |
| semantic_tokens.clj | `lib/src/clojure_lsp/feature/semantic_tokens.clj` | ソース | トークンタイプ判定 |
