# 画面設計書 21-nimsuggest sug（補完）

## 概要

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

### 本画面の処理概要

nimsuggest sugコマンドは、IDE/エディタ連携において、ユーザーがコード編集中にカーソル位置に応じた補完候補を取得するための機能を提供する。

**業務上の目的・背景**：Nimプログラミングにおいて、開発者の生産性向上のためにコード補完機能は不可欠である。この機能により、利用可能な変数名、関数名、型名、フィールド名などをリアルタイムで提示し、タイプミスの防止とコーディング速度の向上を実現する。エディタ/IDE統合において、LSP（Language Server Protocol）的な補完サービスを提供する基盤となる。

**画面へのアクセス方法**：nimsuggestサーバーが起動した状態で、クライアント（エディタ/IDE）から以下のコマンド形式でリクエストを送信する。
- TCP接続の場合: `sug "file.nim":line:col` または `sug "file.nim";"dirtyfile.nim":line:col`
- stdin/EPCモードでも同様のコマンド形式を使用

**主要な操作・処理内容**：
1. クライアントからsugコマンドとファイル位置情報（ファイルパス、行番号、カラム番号）を受信
2. 指定位置のコンテキストを解析し、補完可能なシンボルを収集
3. オーバーロード解決を行い、適切な候補をランク付け
4. 補完候補リスト（シンボル名、型情報、ドキュメント等）を返却

**画面遷移**：
- 遷移元: エディタ/IDEからの補完リクエスト（通常はトリガー文字入力時や明示的な補完呼び出し時）
- 遷移先: 結果はクライアントに返却され、ユーザーに補完候補として表示される

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

## 関連機能

| 機能No | 機能名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 25 | Nimsuggest | 主機能 | ideSugコマンドによるコード補完候補提供 |
| 14 | オーバーロード解決 | 補助機能 | 補完候補のオーバーロード解決 |

## 画面種別

コマンドライン / サーバーレスポンス（補完候補一覧）

## URL/ルーティング

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

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

# stdinモード
nimsuggest --stdin project.nim
# 標準入力からコマンドを送信
```

## 入出力項目

### 入力項目

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

### 出力項目

| 項目名 | 型 | 説明 |
|--------|-----|------|
| section | IdeCmd | `ideSug`固定 |
| symkind | TSymKind | シンボルの種類（skProc, skVar, skType等） |
| qualifiedPath | seq[string] | 完全修飾パス |
| filePath | string | 定義ファイルのパス |
| forth | string | 型シグネチャ |
| line | int | 定義位置の行番号 |
| column | int | 定義位置のカラム番号 |
| doc | string | ドキュメントコメント |
| quality | int | マッチ品質スコア |
| prefix | PrefixMatch | プレフィックスマッチ情報 |

## 表示項目

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

| 表示項目 | 説明 | 例 |
|---------|------|-----|
| シンボル名 | 補完候補の名前 | `echo`, `len`, `add` |
| シンボル種別 | proc/var/type/field等 | `skProc`, `skVar` |
| 型情報 | シンボルの型シグネチャ | `proc (s: string)` |
| ファイル位置 | 定義元ファイルと行番号 | `system.nim:123:5` |
| ドキュメント | docコメントの内容 | `Prints a string to stdout` |

## イベント仕様

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

1. クライアントからsugコマンドを受信
2. `execCmd`関数でコマンドをパース（行517: `of "sug": conf.ideCmd = ideSug`）
3. ファイル、行、カラム情報を抽出
4. `execute`関数を呼び出して補完処理を実行
5. プロトコルバージョン3以上の場合は`executeNoHooksV3`を使用

### 2-補完候補の収集

1. 対象ファイルのダーティ状態をチェック
2. 必要に応じて部分再コンパイルを実行（`recompilePartially`）
3. `conf.m.trackPos`に位置情報を設定
4. セマンティック解析を通じて補完候補を収集
5. `suggestResult`経由で結果を送信

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

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

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

本コマンドはデータベースを使用せず、Nimコンパイラのインメモリモジュールグラフを参照して補完候補を収集する。

## メッセージ仕様

| メッセージ種別 | メッセージ | 発生条件 |
|---------------|----------|---------|
| 成功 | 補完候補リスト（複数行） | 正常に補完候補が見つかった場合 |
| 情報 | `!EOF!` | テスターモード時の終端マーカー |
| エラー | `found no symbol at this position` | 指定位置でシンボルが見つからない場合 |

## 例外処理

| 例外状況 | 処理内容 |
|---------|---------|
| ファイルが存在しない | エラーメッセージを返却 |
| 位置情報が無効 | 空の結果を返却 |
| コンパイルエラー | structuredErrorHookでエラーを収集し、ideChkセクションで返却 |
| 再コンパイル失敗 | フル再コンパイルにフォールバック |

## 備考

- sugコマンドは部分コンパイルをトリガーし、ファイルをダーティとしてマークする
- プロトコルバージョン3以上では`executeNoHooksV3`が使用され、より効率的な増分コンパイルが行われる
- EPCモード（Emacs連携）では結果がS式形式でエンコードされる

---

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

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

### 推奨読解順序

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

まず、nimsuggestで使用される主要なデータ構造を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | suggest.nim | `compiler/suggest.nim` | `Suggest`型の定義、補完結果の構造 |
| 1-2 | options.nim | `compiler/options.nim` | `IdeCmd`列挙型、`ideSug`の定義 |
| 1-3 | ast.nim | `compiler/ast.nim` | `PSym`（シンボル）、`PNode`（AST）の構造 |

**読解のコツ**: Suggestレコードは補完結果の基本単位であり、section, symkind, qualifiedPath, forth（型情報）等のフィールドを持つ。

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

処理の起点となるファイル・関数を特定する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | メインエントリ、コマンドパース処理 |

**主要処理フロー**:
1. **行1298-1299**: `handleCmdLine`がメインエントリ、コマンドライン引数をパース
2. **行622-668**: `mainCommand`でグラフを初期化し、入力スレッドを開始
3. **行582-617**: `mainThread`でリクエストを継続的に処理
4. **行494-571**: `execCmd`でコマンドを解析し、適切な処理を呼び出し

#### Step 3: コマンド処理を理解する

sugコマンドの処理フローを追跡する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | `execCmd`関数、行517でideSugを設定 |
| 3-2 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | `executeNoHooksV3`関数（v3プロトコル）、行1066-1296 |

**主要処理フロー**:
- **行517**: `of "sug": conf.ideCmd = ideSug` - コマンドの識別
- **行1102-1110**: v3でのideSug処理開始
- **行1150-1156**: 部分コンパイルとダーティマーク

#### Step 4: 結果出力を理解する

補完結果の生成と送信方法を理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | `sugResultHook`、`suggestResult`関数 |
| 4-2 | nimsuggest.nim | `nimsuggest/nimsuggest.nim` | `sexp`変換（EPC用）、行152-176 |

**主要処理フロー**:
- **行117-118**: `sugResultHook`で結果をチャネルに送信
- **行905-916**: `suggestResult`でSuggestオブジェクトを構築

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

```
handleCmdLine (行758)
    │
    ├─ processCmdLine (行670) - コマンドライン解析
    │
    └─ mainCommand (行622)
           │
           ├─ compileProject - 初期コンパイル (行649)
           │
           ├─ createThread(replStdin/replTcp/replEpc) - 入力スレッド起動
           │
           └─ mainThread (行582)
                  │
                  └─ execCmd (行494)
                         │
                         ├─ parseIdent - コマンド名解析 (行515)
                         │
                         ├─ parseQuoted - ファイルパス解析 (行552-554)
                         │
                         └─ execute (行296)
                                │
                                └─ executeNoHooks / executeNoHooksV3
                                       │
                                       ├─ recompilePartially (行787)
                                       │
                                       └─ suggestResult (行905)
```

### データフロー図

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

クライアント              nimsuggestサーバー               クライアント
    │                         │                              │
    │  sug "file":line:col    │                              │
    │────────────────────────>│                              │
    │                         │                              │
    │                    execCmd()                           │
    │                         │                              │
    │                    parseコマンド                       │
    │                         │                              │
    │                    executeNoHooksV3()                  │
    │                         │                              │
    │                    recompilePartially()                │
    │                         │                              │
    │                    補完候補収集                        │
    │                         │                              │
    │                    sugResultHook()                     │
    │                         │                              │
    │                         │  Suggest[]                   │
    │<───────────────────────────────────────────────────────│
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| nimsuggest.nim | `nimsuggest/nimsuggest.nim` | ソース | メインエントリ、コマンド処理、結果送信 |
| suggest.nim | `compiler/suggest.nim` | ソース | Suggest型定義、補完ロジック |
| sigmatch.nim | `compiler/sigmatch.nim` | ソース | オーバーロード解決、型マッチング |
| modulegraphs.nim | `compiler/modulegraphs.nim` | ソース | モジュールグラフ管理、シンボル検索 |
| sempass2.nim | `compiler/sempass2.nim` | ソース | セマンティック解析パス2 |
| options.nim | `compiler/options.nim` | ソース | IdeCmd定義、設定管理 |
| msgs.nim | `compiler/msgs.nim` | ソース | メッセージ処理、位置情報管理 |
| sexp.nim | `nimsuggest/sexp.nim` | ソース | S式エンコーディング（EPC用） |
