# 機能設計書: Nimsuggest (No.25)

## 1. 機能概要

### 1.1 機能名
Nimsuggest (nimsuggest/nimsuggest.nim)

### 1.2 機能説明
エディタやIDEにNim言語のIDE機能（コード補完、定義ジャンプ、使用箇所検索、型情報表示等）を提供するサーバーツール。ソケット通信（TCP/EPC）またはstdin/stdoutを通じてエディタと連携し、リアルタイムにコード解析結果を返す。

### 1.3 関連画面
- CLI（コマンドラインインターフェース）
- 各種エディタ連携（VSCode、Emacs、Vim等）

## 2. 機能詳細

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| projectfile.nim | string | Yes | プロジェクトファイル |
| --port | int | No | ポート番号（デフォルト: 6000） |
| --address | string | No | バインドアドレス（デフォルト: 127.0.0.1） |
| --stdin | flag | No | stdin/stdoutモード |
| --epc | flag | No | Emacs EPCモード |
| --autobind | flag | No | 空きポートに自動バインド |
| --v1/--v2/--v3/--v4 | flag | No | プロトコルバージョン指定 |

### 2.2 対応コマンド
| コマンド | 説明 |
|----------|------|
| sug | コード補完候補を取得 |
| con | コンテキスト情報を取得 |
| def | 定義位置にジャンプ |
| use | シンボルの使用箇所を検索 |
| dus | 定義と使用箇所を検索 |
| chk | ファイルの構文/意味チェック |
| mod | モジュール情報を取得 |
| highlight | シンタックスハイライト情報 |
| outline | ドキュメントアウトライン |
| known | ファイルが既知か確認 |
| project | プロジェクトファイルを取得 |
| globalSymbols | グローバルシンボル検索 |
| inlayHints | インレイヒント（型ヒント等） |

### 2.3 処理フロー
1. **初期化**
   - コマンドライン引数解析
   - プロジェクトファイルのセマンティック解析
   - 通信モード決定（stdin/tcp/epc）

2. **サーバー起動**
   - ソケットバインド（TCPモード）
   - チャネル初期化（requests/results）

3. **リクエスト処理ループ**
   - クライアントからのコマンド受信
   - コマンド解析（cmd file:line:col形式）
   - executeNoHooks()でコード解析実行
   - 結果をクライアントに送信

4. **増分更新**
   - dirtyfile指定でメモリ上の編集内容を解析
   - markDirty()でキャッシュ無効化
   - 必要部分のみ再コンパイル

### 2.4 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| Suggest | object | 補完/定義/使用箇所等の結果 |
| ideMsg | section | メッセージ出力 |
| ideChk | section | エラー/警告情報 |

### 2.5 エラーハンドリング
| エラー条件 | 処理 |
|------------|------|
| シンボル未発見 | localError()でエラー出力 |
| 無効なコマンド | Help表示 |
| コンパイルエラー | errorHookで結果に追加 |

## 3. ビジネスルール

### 3.1 プロトコルバージョン
| バージョン | 説明 |
|------------|------|
| v1 | 後方互換性用 |
| v2 | デフォルト |
| v3 | ベンチマーク機能追加 |
| v4 | 最新（HighestSuggestProtocolVersion=4） |

### 3.2 通信フォーマット
#### リクエスト
```
cmd file.nim;dirtyfile.nim:line:col
例: sug /path/to/file.nim:10:5
```

#### レスポンス（Suggest構造体）
```nim
type Suggest = object
  section: IdeCmd
  symkind: TSymKind
  qualifiedPath: seq[string]
  filePath: string
  line, column: int
  doc: string
  quality: range[0..100]
  prefix: PrefixMatch
```

### 3.3 サポート機能
| 機能 | 説明 |
|------|------|
| con | コンテキスト補完サポート |
| exceptionInlayHints | 例外インレイヒント |
| unknownFile | 未知ファイルのハンドリング |

## 4. 技術仕様

### 4.1 使用ライブラリ
- compiler/options, modules, sigmatch, ast
- strutils, os, parseopt, net
- sexp（S式処理）
- rdstdin（対話入力）

### 4.2 主要データ構造
```nim
type
  Mode = enum mstdin, mtcp, mepc, mcmdsug, mcmdcon
  CachedMsg = object
    info: TLineInfo
    msg: string
    sev: Severity
  CachedMsgs = seq[CachedMsg]

var
  requests: Channel[string]
  results: Channel[Suggest]
```

### 4.3 スレッド構成
- メインスレッド: コマンド解析・実行
- 入力スレッド: replStdin/replTcp/replEpc
- 結果出力: toStdout/toSocket/toEpc

### 4.4 キャッシュ管理
```nim
proc clearInstCache(graph: ModuleGraph, projectFileIdx: FileIndex) =
  # 型インスタンスキャッシュのクリア
  graph.typeInstCache.clear()
  graph.procInstCache.clear()
```

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

### 5.1 推奨読解順序

#### 5.1.1 データ構造の理解
1. **nimsuggest.nim 91-110行目**: 型と変数定義
   - Mode列挙型、CachedMsg型
   - グローバル変数（gPort, gAddress, gMode等）
   - Channel定義（requests, results）

2. **nimsuggest.nim 128-139行目**: 定数とCapabilities
   - Help文字列、Capabilities配列

#### 5.1.2 エントリーポイント
3. **nimsuggest.nim main関数**（ファイル末尾）
   - コマンドライン解析
   - モード別スレッド起動

#### 5.1.3 コア処理
4. **nimsuggest.nim 245-295行目**: executeNoHooks関数
   - コマンド実行のメインロジック
   - suggestVersionによる分岐

5. **nimsuggest.nim 296-304行目**: execute関数
   - エラーフック設定

6. **nimsuggest.nim 494行目〜**: execCmd関数
   - コマンド文字列のパースと実行

### 5.2 読解のコツ

#### 通信モードの理解
```nim
case gMode
of mstdin: createThread(inputThread, replStdin, ...)
of mtcp:   createThread(inputThread, replTcp, ...)
of mepc:   createThread(inputThread, replEpc, ...)
```

#### S式処理（EPCモード）
- `sexp()`関数群でNimオブジェクトをS式に変換
- Emacs flycheckとの連携に使用

#### 増分コンパイルの理解
```nim
graph.markDirty dirtyIdx
graph.markClientsDirty dirtyIdx
graph.compileProject(modIdx)
```

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

```
nimsuggest projectfile.nim [options]
  |
  +-- parseopt解析
  +-- プロジェクト初期化
  |     +-- compileProject(mainCommand)
  |
  +-- Channel初期化
  |     +-- requests.open()
  |     +-- results.open()
  |
  +-- [Mode別スレッド起動]
        |
        +-- [mstdin] replStdin()
        |     +-- readLine(stdin)
        |     +-- requests.send(line)
        |     +-- toStdout()
        |
        +-- [mtcp] replTcp()
        |     +-- server.accept(client)
        |     +-- client.readLine(inp)
        |     +-- requests.send(inp)
        |     +-- toSocket(client)
        |
        +-- [mepc] replEpc()
              +-- client.recv(message)
              +-- parseSexp(message)
              +-- requests.send(cmd)
              +-- toEpc(client, uid)

[メインスレッド]
  |
  +-- requests.recv()
  +-- execCmd(cmd, graph)
        +-- parseCmd()
        +-- executeNoHooks(cmd, file, line, col)
              +-- setDirtyFile()
              +-- compileProject()
              +-- listUsages() / suggest() / etc.
        +-- results.send(Suggest)
```

### 5.4 データフロー図

```
[エディタ/IDE]
      |
      | (TCP/stdin/EPC)
      v
[requests Channel] <-- 入力スレッド
      |
      v
[execCmd()]
      |
      +-- [parseCmd] --> cmd, file, line, col
      |
      +-- [executeNoHooks]
      |     |
      |     +-- [compileProject] (必要時)
      |     +-- [symFromInfo] (シンボル検索)
      |     +-- [listUsages] (使用箇所)
      |     +-- [suggest] (補完候補)
      |
      v
[results Channel]
      |
      v
[toStdout/toSocket/toEpc]
      |
      v
[エディタ/IDE]
```

### 5.5 関連ファイル一覧

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| nimsuggest/nimsuggest.nim | メイン | サーバー本体 |
| nimsuggest/sexp.nim | ユーティリティ | S式処理 |
| nimsuggest/procmonitor.nim | ユーティリティ | プロセス監視 |
| compiler/sigmatch.nim | コンパイラ | シンボルマッチング |
| compiler/suggest.nim | コンパイラ | サジェスト機能（include） |
| compiler/suggestsymdb.nim | コンパイラ | シンボルデータベース |
| compiler/modules.nim | コンパイラ | モジュール管理 |

## 6. 変更履歴

| 日付 | 変更者 | 変更内容 |
|------|--------|----------|
| 2026-02-17 | Claude | 初版作成 |
