# 機能設計書: Nimgrep (No.29)

## 1. 機能概要

### 1.1 機能名
Nimgrep (tools/nimgrep.nim)

### 1.2 機能説明
Nim用の高機能なgrep/置換ユーティリティ。正規表現またはPEGパターンによる検索、ファイル内容の置換、再帰的なディレクトリ走査、カラー出力、コンテキスト表示等をサポート。並列処理による高速な検索も可能。

### 1.3 関連画面
- CLI（コマンドラインインターフェース）
- ターミナル（カラー出力）

## 2. 機能詳細

### 2.1 入力
| 項目 | 型 | 必須 | 説明 |
|------|-----|------|------|
| pattern | string | Yes* | 検索パターン |
| paths | string[] | No | 検索対象パス |
| --replace | string | No | 置換文字列 |
| --peg | flag | No | PEGパターン使用 |
| --re | flag | No | 正規表現使用（デフォルト） |
| --recursive | flag | No | 再帰検索 |
| --ignoreCase | flag | No | 大文字小文字無視 |
| --context | int | No | 前後のコンテキスト行数 |
| --ext | string | No | ファイル拡張子フィルタ |
| --workers | int | No | 並列ワーカー数 |
| --stdin | flag | No | 標準入力から読み込み |

### 2.2 出力モード
| モード | 説明 |
|--------|------|
| find | マッチ行を表示 |
| replace | 置換を実行 |
| count | マッチ数のみ表示 |
| filenames | ファイル名のみ表示 |

### 2.3 処理フロー
1. **コマンドライン解析**
   - parseopt/getopt()でオプション取得
   - パターンとパスの設定

2. **ファイル発見**
   - 再帰的ディレクトリ走査
   - 拡張子/ファイル名フィルタ適用

3. **検索実行**
   - 正規表現またはPEGでマッチング
   - コンテキスト行の取得

4. **結果出力**
   - カラー付きターミナル出力
   - 置換モードではファイル更新

### 2.4 出力
| 項目 | 型 | 説明 |
|------|-----|------|
| マッチ情報 | stream | ファイル名、行番号、マッチ内容 |
| 置換済みファイル | file | --replace時 |
| 統計情報 | stream | マッチ数等 |

### 2.5 エラーハンドリング
| エラー条件 | 処理 |
|------------|------|
| ファイル開けない | openErrorとして出力 |
| 無効なパターン | エラーメッセージ表示 |
| バイナリファイル | rejectedとして報告 |

## 3. ビジネスルール

### 3.1 検索結果構造
```
FileResult -> Block -> Output/Chunk -> SubLine
```

| レベル | 説明 |
|--------|------|
| SubLine | 行全体または行の一部 |
| Chunk | マッチとその周辺コンテキスト |
| Block | 連続するChunkのグループ |
| FileResult | ファイル単位の結果 |

### 3.2 フィルタオプション
| オプション | 説明 |
|------------|------|
| --ext | 対象拡張子（例: .nim,.nims） |
| --notExt | 除外拡張子 |
| --filename | ファイル名パターン |
| --notFilename | 除外ファイル名パターン |
| --dirname | ディレクトリ名パターン |
| --notDirname | 除外ディレクトリ名 |

### 3.3 カラーテーマ
| テーマ | 説明 |
|--------|------|
| simple | 基本スタイル |
| bnw | 白黒 |
| ack | ack風カラー |
| gnu | GNU grep風カラー |

## 4. 技術仕様

### 4.1 使用ライブラリ
- os, strutils, parseopt
- pegs, re
- terminal, osproc
- tables, algorithm, times

### 4.2 主要データ構造
```nim
type
  TOption = enum
    optFind, optReplace, optPeg, optRegex, optRecursive,
    optConfirm, optStdin, optWord, optIgnoreCase, ...

  MatchInfo = tuple[first: int, last: int;
                    lineBeg: int, lineEnd: int, match: string]

  Output = object
    case kind: outputKind
    of openError: msg: string
    of rejected: reason: string
    of justCount: matches: int
    of blockFirstMatch, blockNextMatch:
      pre: string
      match: MatchInfo
    of blockEnd: blockEnding: string; firstLine: int
    of fileContents: buffer: string
    of outputFileName: name: string

  FileResult = seq[Output]
```

### 4.3 並列処理
```nim
var nWorkers = 0  # デフォルトはシングルスレッド
var searchRequestsChan: Channel[Trequest]
var resultsChan: Channel[Tresult]
```

### 4.4 パターン処理
```nim
type Pattern = Regex | Peg

proc beforePattern(s: string, pos: int, nLines = 1): int
proc afterPattern(s: string, pos: int, nLines = 1): int
```

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

### 5.1 推奨読解順序

#### 5.1.1 データ構造の理解
1. **nimgrep.nim 60-131行目**: 型定義
   - TOption列挙、MatchInfo、Output、FileResult

2. **nimgrep.nim 133-160行目**: グローバル変数
   - options, walkOpt, searchOpt, colorTheme等

#### 5.1.2 エントリーポイント
3. **nimgrep.nim main関数**（ファイル末尾）
   - コマンドライン解析と検索実行

#### 5.1.3 コア処理
4. **nimgrep.nim 188-219行目**: beforePattern/afterPattern
   - コンテキスト行の取得

5. **nimgrep.nim 227-298行目**: printXxx関数群
   - カラー出力処理

6. **nimgrep.nim 177行目**: countLineBreaks
   - 行カウント処理

### 5.2 読解のコツ

#### Output型のcase分岐
```nim
case kind: outputKind
of openError: ...  # ファイル開けない
of rejected: ...   # フィルタで除外
of justCount: ...  # --count時
of blockFirstMatch, blockNextMatch: ...  # 通常のマッチ
of blockEnd: ...   # ブロック終端
of fileContents: ... # --replace時
of outputFileName: ... # --filenames時
```

#### カラーテーマ分岐
```nim
case colorTheme
of "simple": stdout.write(s)
of "bnw": stdout.styledWrite(styleUnderscore, s)
of "ack": stdout.styledWrite(fgGreen, s)
of "gnu": stdout.styledWrite(fgMagenta, s)
```

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

```
nimgrep [options] PATTERN [paths]
  |
  +-- main()
        |
        +-- parseopt.getopt()
        |     +-- オプション解析
        |     +-- paths設定
        |
        +-- [--stdin]
        |     +-- stdin.readAll()
        |     +-- search()
        |
        +-- [paths指定]
              |
              +-- [--recursive]
              |     +-- walkDirRec()
              |           +-- フィルタ適用
              |
              +-- for path in paths:
                    +-- search(path)
                          |
                          +-- readFile(path)
                          +-- [--peg] matches(peg)
                          +-- [--re] findAll(re)
                          |
                          +-- [マッチ毎]
                          |     +-- beforePattern()
                          |     +-- afterPattern()
                          |     +-- Output生成
                          |
                          +-- [--replace]
                          |     +-- replacef()
                          |     +-- writeFile()
                          |
                          +-- 結果出力
                                +-- printXxx()
```

### 5.4 データフロー図

```
[コマンドライン引数]
        |
        v
[parseopt] --> TOptions, WalkOpt, SearchOpt
        |
        v
[ファイル発見]
  +-- walkDirRec()
  +-- フィルタ (ext, filename, dirname)
        |
        v
[ファイル読み込み]
        |
        v
[パターンマッチ]
  +-- Regex.findAll() / Peg.match()
        |
        v
[MatchInfo生成]
  +-- (first, last, lineBeg, lineEnd, match)
        |
        v
[コンテキスト取得]
  +-- beforePattern()
  +-- afterPattern()
        |
        v
[Output生成] --> FileResult
        |
        v
[出力]
  +-- printFile(), printLineN()
  +-- writeColored()
  +-- [--replace] writeFile()
```

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

| ファイルパス | 種別 | 役割 |
|-------------|------|------|
| tools/nimgrep.nim | メイン | 検索/置換ツール本体 |
| doc/nimgrep_cmdline.txt | ドキュメント | コマンドラインヘルプ |
| koch.nim (258-259行目) | ビルド | nimgrepビルド呼び出し |

## 6. 変更履歴

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