# 画面設計書 26-nimsuggest outline（アウトライン）

## 概要

本ドキュメントは、Nimsuggestツールの`outline`（アウトライン）サブコマンドに関する画面設計書である。

### 本画面の処理概要

nimsuggest outlineコマンドは、IDE/エディタ連携において、ファイル内のシンボル一覧（アウトライン）を取得する機能を提供する。プロシージャ、型定義、定数、変数などの定義をツリー構造で表示するための情報を返す。

**業務上の目的・背景**：大規模なソースファイルでは、多数の関数や型が定義されており、目的のコードを見つけることが困難になる。この機能により、エディタのサイドバーにシンボル一覧を表示し、クリックで該当位置にジャンプできるようになる。これはコードナビゲーションの基本機能であり、開発効率を大幅に向上させる。

**画面へのアクセス方法**：nimsuggestサーバーが起動した状態で、クライアント（エディタ/IDE）から以下のコマンド形式でリクエストを送信する。
- TCP接続の場合: `outline "file.nim":line:col`
- stdin/EPCモードでも同様のコマンド形式を使用
- 通常、ファイルを開いた時やファイル保存時に自動的にトリガーされる

**主要な操作・処理内容**：
1. クライアントからoutlineコマンドとファイル情報を受信
2. 対象ファイルをパースしてASTを取得
3. 定義ノード（proc, type, const, var等）を走査
4. 各定義のシンボル名、位置、種類を返却

**画面遷移**：
- 遷移元: エディタ/IDEからのアウトラインリクエスト
- 遷移先: 結果はクライアントに返却され、アウトラインビューとして表示

**権限による表示制御**：本ツールはCLI/サーバーベースであり、権限による表示制御は存在しない。

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | Nimsuggest | 主機能 | ideOutlineコマンドによるファイルアウトライン情報取得 |

## 画面種別

コマンドライン / サーバーレスポンス（アウトライン情報一覧）

## URL/ルーティング

```
# コマンド形式
outline "filepath.nim":line:col
outline "filepath.nim";"dirtyfile.nim":line:col

# TCPモード
nimsuggest --port:6000 project.nim
# その後、ソケット接続して上記コマンドを送信
```

## 入出力項目

### 入力項目

| 項目名 | 型 | 必須 | 説明 |
|--------|-----|------|------|
| file | string | Yes | 対象ファイルのパス |
| dirtyfile | string | No | 編集中の一時ファイルパス |
| line | int | Yes | 行番号（1始まり） |
| col | int | Yes | カラム番号（0始まり） |

### 出力項目（複数行で返却）

| 項目名 | 型 | 説明 |
|--------|-----|------|
| section | IdeCmd | `ideOutline`固定 |
| symkind | TSymKind | シンボルの種類（skProc, skType等） |
| qualifiedPath | seq[string] | 完全修飾パス |
| filePath | string | ファイルパス |
| line | int | 定義位置の行番号 |
| column | int | 定義位置のカラム番号 |
| endLine | int | 定義終了位置の行番号（v3） |
| endCol | int | 定義終了位置のカラム番号（v3） |

## 表示項目

アウトライン情報として以下の情報がクライアントに返される:

| 表示項目 | 説明 | 例 |
|---------|------|-----|
| シンボル名 | 定義されたシンボルの名前 | `myFunction`, `MyType` |
| シンボル種別 | 定義の種類 | `skProc`, `skType`, `skConst` |
| 開始行番号 | 定義の開始行 | `10` |
| 終了行番号 | 定義の終了行（v3プロトコル） | `25` |

## イベント仕様

### 1-outlineコマンド受信

1. クライアントからoutlineコマンドを受信
2. `execCmd`関数でコマンドをパース（行525: `of "outline": conf.ideCmd = ideOutline`）
3. ファイル情報を抽出
4. `execute`関数を呼び出してアウトライン取得処理を実行

### 2-アウトライン情報の取得

1. 対象ファイルをパース（`parseFile`）
2. ASTを走査してアウトラインノードを抽出（`iterateOutlineNodes`）
3. 各定義のシンボル情報を収集
4. `suggestResult`で結果を送信

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

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

| 操作（イベント） | 対象テーブル | 操作種別 | 概要 |
|----------------|-------------|---------|------|
| - | - | - | データベースへの更新は発生しない |

## メッセージ仕様

| メッセージ種別 | メッセージ | 発生条件 |
|---------------|----------|---------|
| 成功 | アウトラインリスト（複数行） | 正常にシンボルが見つかった場合 |
| 情報 | 空の結果 | 定義がない空ファイルの場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ファイルが存在しない | エラーメッセージを返却 |
| パースエラー | エラー情報を返却 |

## 備考

- outlineコマンドはパースのみで動作し、完全なコンパイルは不要
- v3プロトコルでは終了位置（endLine, endCol）も返却される
- 対象となるノード種別: nkFuncDef, nkProcDef, nkTypeDef, nkMacroDef, nkTemplateDef, nkConverterDef, nkEnumFieldDef, nkConstDef
- モジュールレベルまたは型内の定義が対象（ローカル定義は除外）

---

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

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

### 推奨読解順序

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | ast.nim | `compiler/ast.nim` | PNode型、ノード種別 |
| 1-2 | suggest.nim | `compiler/suggest.nim` | Suggest型のendLine/endCol |

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

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | 行525でideOutlineを設定 |

**主要処理フロー**:
1. **行525**: `of "outline": conf.ideCmd = ideOutline`

#### Step 3: アウトライン取得処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | 行1157-1159 - ideOutline処理 |
| 3-2 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | 行1038-1052 - iterateOutlineNodes |
| 3-3 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | 行1012-1027 - outlineNode |

**主要処理フロー**:
- **行1157-1159**: ideOutline処理ブロック
```nim
of ideOutline:
  let n = parseFile(fileIndex, graph.cache, graph.config)
  graph.iterateOutlineNodes(n, graph.fileSymbols(fileIndex).deduplicateSymInfoPair(false))
```

- **行1038-1052**: iterateOutlineNodes関数
```nim
proc iterateOutlineNodes(graph: ModuleGraph, n: PNode, infoPairs: SuggestFileSymbolDatabase) =
  # 対象ノード種別をチェック
  if (n.kind in {nkFuncDef, nkProcDef, nkTypeDef, nkMacroDef, nkTemplateDef, nkConverterDef, nkEnumFieldDef, nkConstDef}):
    matched = handleIdentOrSym(graph, n, n.endInfo, infoPairs)
  # 子ノードを再帰的に走査
  for child in n:
    graph.iterateOutlineNodes(child, infoPairs)
```

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

```
execCmd (行494)
    │
    ├─ parseIdent - "outline"コマンド解析 (行525)
    │
    └─ executeNoHooksV3 (行1066)
           │
           ├─ recompilePartially (必要時)
           │
           ├─ parseFile - ASTを取得
           │
           └─ iterateOutlineNodes
                  │
                  ├─ outlineNode - 個別ノード処理
                  │
                  └─ suggestResult - 結果送信
```

### データフロー図

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

クライアント               nimsuggestサーバー            クライアント
    │                          │                           │
    │  outline "file":1:0      │                           │
    │─────────────────────────>│                           │
    │                          │                           │
    │                     parseFile()                      │
    │                          │                           │
    │                     AST走査                          │
    │                          │                           │
    │                     定義ノード抽出                   │
    │                          │                           │
    │                          │  Suggest[] (複数)         │
    │<────────────────────────────────────────────────────│
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nimsuggest.nim | `nimsuggest/nimsuggest.nim` | ソース | ideOutline処理、AST走査 |
| syntaxes.nim | `compiler/syntaxes.nim` | ソース | parseFile関数 |
| ast.nim | `compiler/ast.nim` | ソース | ノード種別定義 |
| suggestsymdb.nim | `compiler/suggestsymdb.nim` | ソース | シンボルDB参照 |
