`-U` merges adjacent matches: `-o`, `--vimgrep`, `--count-matches` and `--json` report one match instead of two
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
調査の方向性
tgrep-cli/src/matching.rsから始め、特にgroup_spans_by_line、FileMatches::find、match_countを確認し、その後、既存のgroup_spans_merges_overlapping_ranges_on_one_lineテストを読みます。複数行モードでパターンaをaaに対して使い、再現コマンドを実行して、影響を受ける出力モードの回帰テストを追加します。隣接するマッチが別々のままであり、カウントと出力が一致することをテストで確認できれば完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
With -U/--multiline, matches that touch each other on the same line are merged into one span. -o, --vimgrep, --count-matches and --json then report fewer, longer matches than ripgrep. --stats still counts them correctly, so the counts tgrep reports disagree with each other.
Without -U the same search reports each match separately, as ripgrep does.
Reproduce
mkdir repro && cd repro
printf 'aa\n' > a.txt
tgrep --no-index -U -o -n a a.txt
tgrep --no-index -U --vimgrep a a.txt
tgrep --no-index -U --count-matches a a.txt
tgrep --no-index -U --json a a.txt
tgrep --no-index -U --stats a a.txt
tgrep --no-index -o -n a a.txt # control: without -U
| Query | Actual: tgrep | Expected: rg 15.1.0 |
|---|---|---|
-U -o -n |
1:aa |
1:a, 1:a |
-U --vimgrep |
a.txt:1:1:aa |
a.txt:1:1:aa, a.txt:1:2:aa |
-U --count-matches |
1 |
2 |
-U --json |
one submatch aa (0–2); "matches":1 |
two submatches a (0–1, 1–2); "matches":2 |
-U --stats |
2 matches (1 matched lines) |
— |
-o -n (no -U) |
1:a, 1:a |
1:a, 1:a |
The README states that under -U, "--vimgrep reports one row per match, on its starting line".
Environment
- tgrep 1.1.0, built from 1120aca (current
main) with rustc 1.95.0 (59807616e 2026-04-14) - Windows 11 Pro (build 28000); the code involved is platform-independent
- Same results with
--no-index, with a local index, and throughtgrep serve(checked for-oand--count-matches)
Cause
In multiline mode, FileMatches::find passes the regex spans to group_spans_by_line, which merges a span into the previous one when span.0 <= last.1:
So the touching spans (0, 1) and (1, 2) become (0, 2). match_totals counts the spans before merging, which is why --stats says 2. match_count, used by --count-matches, and the per-match output of -o, --vimgrep and --json use the merged spans.
Possible fix
Regex matches never overlap, so merging only needs to join spans that really overlap: span.0 < last.1 keeps touching matches apart and still satisfies group_spans_merges_overlapping_ranges_on_one_line. Alternatively, keep the original spans for per-match output and --count-matches, and merge only for highlighting.
A regression test could check the queries above for aa with pattern a.
- 主要言語
- Rust
- スター
- 3.4k
- フォーク
- 138
- 平均マージ
- 12時間 47分
- マージ済み PR(30日)
- 30
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
microsoft/tgrep のほかの issue
-
難易度 3/5 1〜2日 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 4/5 3〜5日 初心者へのやさしさ 57/100
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 76/100
メンテナーはふだん 1 日以内に返信
-
難易度 3/5 1〜2日 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
microsoft/tgrep の issue をすべて見る
似ている issue
-
agent:triaged bug bughunt pm:npm priority:p1
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
SocketDev/socket-patch#1127 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
documentation enhancement
難易度 2/5 1〜3時間 初心者へのやさしさ 62/100
adorsys/status-list-server#619 ·
メンテナーはふだん 2 日以内に返信
-
batch-backport only backports the first 30 matching PRs対応中かも @DvirDukhan が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
メンテナーはふだん 5 日以内に返信
-
Configuration-level resource: `Allocate` rejects the kubelet's re-offer of the same device for a later container of the same Pod ("Unable to claim slot")対応中かも @fang80913 が 38 日前に担当しました。 オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
project-akri/akri#854 ·