agent: Fix edit_file failing to match exact mid-line old_text fragments (#61489)

Fixes the `edit_file` tool failing to resolve `old_text` fragments that
only cover part of a longer line. The streaming matcher compared the
query against whole trimmed buffer lines, so an exact substring like
`keyboard WASD, voxel-based` inside a much longer line failed the fuzzy
similarity threshold and the edit was rejected with "did not match any
content".

Supersedes #60615 — thanks to @ziimakc for the report, reproduction, and
initial investigation there. This PR takes a different approach based on
review feedback on that PR.

## Approach

- `StreamingFuzzyMatcher::push()` is unchanged: it still fuzzy-matches
completed lines incrementally so the UI can reveal the likely edit
location while `old_text` streams in.
- `finish()` now first searches the buffer for the complete raw query as
an exact byte substring (rope-native, overlap-aware KMP; no copy of the
buffer). Exact matches take precedence; fuzzy matching remains the
fallback for indentation drift, typos, and inserted/omitted lines.
- Exact matches are capped at two occurrences — enough to prove
ambiguity — and ambiguous or overlapping matches are rejected with the
existing "matched multiple locations" error instead of silently editing
one.
- The matcher now returns match candidates with their line alignment and
exact/fuzzy provenance in one result, and the edit pipeline uses that to
reindent correctly: for an exact mid-line match the first replacement
line keeps the retained prefix (zero delta) while subsequent lines get
the contextual indentation.
- The streaming parser now preserves the trailing newline of finalized
`old_text` (it still strips it from `new_text` to avoid duplicate line
endings, per #52661), so `"foo\n"` can disambiguate a standalone `foo`
line from `foo suffix`.

## Notes

- Exact-search cost is O(buffer + query) at finalization only; the
buffer is never copied into a `String` (the main concern with the
original PR).
- New regression tests cover mid-line fragments, exact-over-fuzzy
precedence, overlapping-match ambiguity, multiline replacement
indentation (spaces and tabs), trailing-newline disambiguation, and
newline-only edits.

Closes https://github.com/zed-industries/zed/issues/59369

Release Notes:

- Fixed agent edits failing when the text to replace is only part of a
line
f8851b686cMartinYe1234 committed on 7/23/2026, 5:05:53 PM· committed by GitHubparentb2a4fb4
4 files changedLine totals unavailable