Skip to content

Commit 4c63a03

Browse files
committed
Address search focus review findings (#4618)
1 parent a3e7e9f commit 4c63a03

5 files changed

Lines changed: 93 additions & 19 deletions

File tree

DEVELOPER_GUIDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,7 +1324,7 @@ Exact-match flag compatibility is documented in [USER_GUIDE.md](USER_GUIDE.md#fl
13241324

13251325
`search --json` and MCP `search` project full chunks into compact match-centered snippets with `chunk_start_line`, `chunk_end_line`, `snippet_start_line`, `snippet_end_line`, `snippet`, `match_lines`, `highlights`, `context_before`, `context_after`, `truncated_line_count`, `dropped_match_line_count`, and `truncation_context`. Compact CLI rows and MCP search results also echo effective output options with `snippet_lines` / `snippetLines`, `max_line_width` / `maxLineWidth`, `exact`, `raw_fts` / `rawFts`, `literal_highlights_available` / `literalHighlightsAvailable`, and optional `literal_highlight_warning` / `literalHighlightWarning`. `--snippet-lines` caps the snippet length up front (default: 8, max: 20), and `--max-line-width` (CLI) / `maxLineWidth` (MCP) clamps each individual snippet line around the first match token via the shared `LineWidthFormatter.ClampLine` contract used by `find` / `references` / `excerpt` / `inspect` (default: 512, max: 4096) so a single match inside a minified / transpiled / generated single-line file no longer returns hundreds of KB per hit. Clamped lines surface `...(+N)...` markers inside the snippet and expose `truncation_context.char_counts`, `truncation_context.total_chars`, `highlights[].truncated`, `highlights[].original_line_length`, and `highlights[].truncated_char_counts` so AI clients can detect clamping and quantify omitted characters. `highlights[].terms` remains a distinct term list for compatibility; `highlights[].term_occurrences` records every matched occurrence with `term`, 1-based `line`, 1-based `column`, `length`, plus `visible`, `visible_column`, and `visible_length` for the portion still present in the returned snippet text after line clamping. Exact substring search also adds `highlights[].literal_terms` and `highlights[].literal_term_occurrences` (camelCase in MCP) so clients can render only the requested literal phrase while preserving the broader diagnostic token list; raw FTS rows set `literal_highlight_warning` / `literalHighlightWarning` to `literal_highlights_unavailable_raw_fts` because FTS syntax can no longer be mapped to one literal phrase. Non-exact punctuation-heavy code-phrase searches add `exact_substring_hint` to CLI JSON compact results and `recovery_hint` to MCP `search` responses so clients can retry with exact substring semantics when FTS tokenization is likely to hide punctuation. `focus_mode`, `focus_line`, `focus_column`, and `focus_reason` describe the match window selected for the snippet, while `dropped_match_line_count` and optional `next_match` report match lines omitted because they fell outside that selected snippet window.
13261326

1327-
Default `quality` snippet focus treats a single query made only of letters, digits, and underscores as identifier-shaped. When a result mixes matching code with earlier comments or strings, the first `code`-origin match becomes the preferred snippet line; space-delimited phrase queries and explicit `leftmost` / `proximity` focus modes retain their existing selection. The selected line remains auditable through the existing focus and origin metadata, and `next_match` continues from the selected window.
1327+
Default `quality` snippet focus treats a single query that begins with a letter or underscore and otherwise contains only letters, digits, and underscores as identifier-shaped. When a result mixes matching code with earlier comments or strings, the first `code`-origin occurrence supplies both the preferred snippet line and column, including when a literal and executable occurrence share one long line; space-delimited phrase queries and explicit `leftmost` / `proximity` focus modes retain their existing selection. The selected occurrence remains auditable through the existing focus and origin metadata, `dropped_match_line_count` is computed from the final returned window, and `next_match` continues forward from that window.
13281328

13291329
When the match line falls inside an indexed symbol range, `search --json` and MCP `search` also include optional `enclosing_symbol_name`, `enclosing_symbol_kind`, `enclosing_symbol_start_line`, `enclosing_symbol_end_line`, and `enclosing_container_name`.
13301330

@@ -4193,7 +4193,7 @@ literal-safe な `search` query は reader 層で FTS5 sanitization 前に 1000
41934193

41944194
`search --json` と MCP の `search` は、フルチャンクを `chunk_start_line`、`chunk_end_line`、`snippet_start_line`、`snippet_end_line`、`snippet`、`match_lines`、`highlights`、`context_before`、`context_after`、`truncated_line_count`、`dropped_match_line_count`、`truncation_context` を持つ軽量スニペットへ投影します。compact CLI row と MCP search result は有効な出力オプションも `snippet_lines` / `snippetLines`、`max_line_width` / `maxLineWidth`、`exact`、`raw_fts` / `rawFts`、`literal_highlights_available` / `literalHighlightsAvailable`、任意の `literal_highlight_warning` / `literalHighlightWarning` として返します。`--snippet-lines` で抜粋長を先に制限でき(デフォルト: 8、最大: 20)、`--max-line-width`(CLI)/ `maxLineWidth`(MCP)は `find` / `references` / `excerpt` / `inspect` と同じ共有 `LineWidthFormatter.ClampLine` 契約(デフォルト: 512、最大: 4096、`0` で切り詰め解除)で各スニペット行を最初のマッチトークン周辺にクランプするため、minified / transpiled / 生成された 1 行ファイル内の 1 ヒットで数百 KB を返さなくなります。クランプされた行はスニペットに `...(+N)...` マーカーが入り、`truncation_context.char_counts`、`truncation_context.total_chars`、`highlights[].truncated`、`highlights[].original_line_length`、`highlights[].truncated_char_counts` で AI クライアントがクランプの有無と省略文字数を検出できます。`highlights[].terms` は互換性のため distinct な term list のまま残し、`highlights[].term_occurrences` は一致ごとの `term`、1-based の `line` / `column`、`length` に加えて、行クランプ後に返却 snippet text 内へ残っている部分を示す `visible`、`visible_column`、`visible_length` を記録します。exact substring search では `highlights[].literal_terms` と `highlights[].literal_term_occurrences`(MCP では camelCase)も追加され、広めの診断 token list を残したまま、要求された literal phrase だけを render できます。raw FTS row は FTS 構文を単一の literal phrase へ対応付けられないため、`literal_highlight_warning` / `literalHighlightWarning` に `literal_highlights_unavailable_raw_fts` を設定します。exact ではない記号の多い code phrase 検索では、FTS tokenization が記号を失いやすい場合に exact substring semantics で再検索できるよう、CLI JSON compact result に `exact_substring_hint`、MCP `search` に `recovery_hint` を追加します。`focus_mode`、`focus_line`、`focus_column`、`focus_reason` は snippet に選ばれた match window を説明し、`dropped_match_line_count` と任意の `next_match` は選択された snippet window 外に落ちた一致行を示します。
41954195

4196-
既定の `quality` snippet focus は、文字、数字、underscore だけで構成される単一 query を identifier 形状として扱います。一つの result に一致する code と、それより前の comment / string が混在する場合は、最初の `code` origin match を snippet の優先行にします。空白区切りの phrase query と、明示的な `leftmost` / `proximity` focus mode は従来の選択を維持します。選択行は既存の focus / origin metadata で監査でき、`next_match` は選択された window の先を引き続き示します。
4196+
既定の `quality` snippet focus は、先頭が文字または underscore で、残りが文字、数字、underscore だけで構成される単一 query を identifier 形状として扱います。一つの result に一致する code と、それより前の comment / string が混在する場合は、最初の `code` origin occurrence の行と列を snippet の優先位置にします。同じ長い行に literal と実行 code の occurrence がある場合も code 側を選びます。空白区切りの phrase query と、明示的な `leftmost` / `proximity` focus mode は従来の選択を維持します。選択位置は既存の focus / origin metadata で監査でき、`dropped_match_line_count` は最終的に返す window から計算し、`next_match` はその window の先を引き続き示します。
41974197

41984198
マッチ行がインデックス済みシンボル範囲内にある場合、`search --json` と MCP の `search` は任意フィールドの `enclosing_symbol_name`、`enclosing_symbol_kind`、`enclosing_symbol_start_line`、`enclosing_symbol_end_line`、`enclosing_container_name` も返します。
41994199

TESTING_GUIDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Use `docs/test-doc-maintenance-plan.md` before moving oversized suites or adding
5353

5454
- `ChunkSplitterTests.cs`, `SymbolExtractorTests.cs`, `ReferenceExtractorTests.cs`, `SearchSnippetFormatterTests.cs`, `DbPathResolverTests.cs`, `ExcerptRecoveryCommandFormatterTests.cs`, `ConsoleUiTests.cs`
5555
Pure or mostly pure behavior tests with in-memory inputs.
56-
Search snippet origin-priority coverage keeps PascalCase, snake_case, and phrase queries in one mixed comment/string/code fixture so identifier focus and the phrase control share the same `next_match` boundary.
56+
Search snippet origin-priority coverage keeps PascalCase, snake_case, and phrase queries in one mixed comment/string/code fixture so identifier focus, same-line code-column clamping, final-window dropped counts, and the phrase control share one contract fixture.
5757
Recovery-command coverage asserts structured argv, current `dotnet`/apphost prefix preservation, replay of option-like paths, and display-only escaping for both POSIX sh and PowerShell, including spaces, quotes, dollar signs, and shell metacharacters.
5858
Console writer synchronization coverage yields between character writes instead of sleeping per character; use enough whole-line iterations to expose interleaving without adding wall-clock delay.
5959
- `SymbolExtractor*Tests.cs` and `ReferenceExtractor*Tests.cs`
@@ -757,7 +757,7 @@ dotnet test --filter "FullyQualifiedName~GitHelperTests"
757757

758758
- `ChunkSplitterTests.cs``SymbolExtractorTests.cs``ReferenceExtractorTests.cs``SearchSnippetFormatterTests.cs``DbPathResolverTests.cs``ExcerptRecoveryCommandFormatterTests.cs``ConsoleUiTests.cs`
759759
インメモリ入力中心の、純粋またはほぼ純粋な振る舞いのテスト。
760-
search snippet の origin 優先順位 coverage は PascalCase、snake_case、phrase query を単一の comment / string / code 混在 fixture にまとめ、identifier focusphrase の control が同じ `next_match` 境界を共有するようにします
760+
search snippet の origin 優先順位 coverage は PascalCase、snake_case、phrase query を単一の comment / string / code 混在 fixture にまとめ、identifier focus、同一行の code 列への clamping、最終 window の dropped count、phrase の control を一つの contract fixture で検証します
761761
recovery command の coverage では構造化 argv、現在の `dotnet` / apphost prefix の維持、option と紛らわしい path の再実行、POSIX sh と PowerShell 双方の表示専用 escaping を、空白、quote、dollar sign、shell metacharacter を含めて検証します。
762762
console writer synchronization coverageは文字writeごとのsleepではなくyieldを使い、wall-clock delayを追加せずinterleavingを露出できる十分なwhole-line iterationを維持してください。
763763
- `SymbolExtractor*Tests.cs``ReferenceExtractor*Tests.cs`

changelog.d/unreleased/4618.fixed.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ affected:
1111

1212
## English
1313

14-
- **Identifier searches now focus executable code ahead of comments and strings (#4618)** — default `quality` snippets prefer the first `code`-origin match for PascalCase, snake_case, and other identifier-shaped queries while preserving phrase-query focus metadata and `next_match` navigation.
14+
- **Identifier searches now focus executable code ahead of comments and strings (#4618)** — default `quality` snippets prefer the first `code`-origin line and column for PascalCase, snake_case, and other identifier-shaped queries, including mixed-origin long lines, while preserving phrase-query behavior and accurate dropped-match navigation.
1515

1616
## 日本語
1717

18-
- **識別子検索は comment や string より実行 code を先に focus するようになりました (#4618)** — 既定の `quality` snippet は PascalCase、snake_case、その他の identifier 形状 query で最初の `code` origin match を優先しつつ、phrase query の focus metadata と `next_match` navigation を維持します。
18+
- **識別子検索は comment や string より実行 code を先に focus するようになりました (#4618)** — 既定の `quality` snippet は PascalCase、snake_case、その他の identifier 形状 query で最初の `code` origin の行と列を優先し、複数 origin が混在する長い行にも対応しつつ、phrase query の動作と正確な dropped-match navigation を維持します。

0 commit comments

Comments
 (0)