> [!left-bubble] ![[claude-san-minichara.webp]]
> 本ページの内容は[[Claude Code]]がまとめた実装ログです。
---
## 概要
Obsidian Another Quick Switcherプラグインのgrep機能に、スペース区切りのAND検索機能を実装し、外部依存をfdからripgrepに統一した。
## 実施内容
### 1. 初期調査とAND検索実装方針決定
- **課題**: GrepModalでスペース区切りクエリがAND検索として動作しない
- **調査**: InFileModalに既存のAND検索実装を発見(`smartWhitespaceSplit`と`queries.every()`パターン)
- **技術的選択肢**:
1. 正規表現の先読みアサーション(`(?=.*word1)(?=.*word2).*`)
2. 複数ripgrep実行による結果マージ
- **決定**: Plan 1(先読みアサーション)から開始
### 2. 先読みアサーション方式の実装と問題発見
- **実装**: lookahead assertionsとPCRE2フラグを使用
- **致命的問題**: ハイライトが行全体になってしまう
- 正規表現が行全体にマッチするため、個別の単語ハイライトが不可能
- **ユーザー要請**: ハイライト精度を重視し、複数ripgrep実行方式に変更
### 3. 複数ripgrep実行方式の実装
- **アーキテクチャ**: 各クエリごとに個別ripgrep実行→結果をクライアント側でマージ
- **新規実装**:
- `mergeAndFilterResults`: AND論理で結果をフィルタリング
- `convertSubmatchesToCharPositions`: UTF-8→UTF-16位置変換
- `byteToCharPosition`: バイト位置から文字位置への変換
- `mergeOverlappingSubmatches`: 重複マッチの統合
### 4. 文字位置変換問題の解決
- **問題1**: 「`あ[[Claude Code]]い`」→「`あ[[ClClaude Code]]い`」
- **原因**: ripgrepのUTF-8バイト位置 vs JavaScriptのUTF-16文字位置
- **解決**: `byteToCharPosition`関数で正確な変換
- **問題2**: 「📜abcdClaude Code」→「📜abClaude Code」
- **原因**: 絵文字のサロゲートペア処理
- **解決**: `[...text]`によるUnicodeコードポイント対応
### 5. ファイル名検索のfd削除とripgrep統一
- **問題**: fdはAND検索に対応しておらず、`queries[0]`のみ使用
- **解決**: `rgFiles`関数でripgrepの`--files`オプションを使用
- **実装**:
- 全ファイル取得後、JavaScriptでANDフィルタリング
- 複数クエリに対応したハイライト処理
### 6. 外部依存の完全削除
- **削除対象**:
- Settings interface: `fdCommand`プロパティ
- DEFAULT_SETTINGS: `fdCommand`デフォルト値
- 設定画面UI: fd command設定項目
- commands.ts: fd存在チェック処理
- utils/fd.ts: ファイル全体
- **設定説明文修正**: 「fd is required.」を削除
### 7. テストとドキュメント整備
- **テスト追加**:
- `GrepModal.test.ts`: AND検索マージロジック
- `grep-utils.test.ts`: UTF-8/UTF-16変換とサロゲートペア
- **テスト削除**: `ripgrep.test.ts`(Mock化困難で実用価値低)
- **ドキュメント更新**:
- README.md: fd依存削除、AND検索機能説明追加
- CLAUDE.md: メモリーセクションに技術詳細記録
### 8. リリース作業
- **コミット分割**:
1. `feat(grep): Add space-separated AND search functionality`
2. `feat(grep): Remove fd dependency for unified ripgrep-based search`
- **リリース**: v13.10.0を正常にリリース
## 技術的学習ポイント
### 文字エンコーディングと位置変換
- ripgrep(UTF-8バイト位置)とJavaScript(UTF-16文字位置)の違い
- Unicode絵文字のサロゲートペア処理の重要性
- `Buffer.from(codePoint, 'utf8').length`による正確なバイト計算
### テスト戦略
- Mock化が困難で実装と乖離するテストは削除する
- 実際の関数呼び出しなしに別ロジックをテストするのは意味がない
### 外部依存削除の注意点
- 設定インターフェース、デフォルト値、UI、チェック処理、説明文、READMEを一貫して更新
- 部分的な削除は起動エラーの原因となる
### リファクタリング判断基準
- 共通化による抽象化が自明でない場合は避ける
- 5行程度の重複は必ずしもヘルパー関数化する価値なし
## 今後の注意点
1. **AND検索の拡張**: 将来的に他のモーダルでも同様のパターンが使用可能
2. **文字位置変換**: 多言語対応やUnicode処理時は必ず位置変換を考慮
3. **外部依存変更**: 依存削除時は全関連箇所の一貫した更新が必須
4. **テスト方針**: Mock化困難な処理は実用価値を重視して判断
## 成果
- ✅ スペース区切りAND検索機能の実装
- ✅ ripgrepへの依存統一(fdからの移行)
- ✅ 正確な文字位置ハイライト(多言語・絵文字対応)
- ✅ 設定の簡素化(fd関連削除)
- ✅ 包括的なテストカバレッジ
- ✅ ドキュメント更新
- ✅ v13.10.0リリース完了