agent_ui: Add in-thread search bar#57231
Open
dandv wants to merge 8 commits into
Open
Conversation
This was referenced May 20, 2026
Member
|
@dandv I like the feature idea! Will send to the team to give more detailed feedback |
b0250b2 to
ae5567d
Compare
5 tasks
ccc8fde to
5edee1c
Compare
5 tasks
7e03a02 to
cd5bc8e
Compare
Member
|
Thanks for working on this. Looks promising, I'll try to look at this PR this week. Is there anything you'd like to get in before I start making changes @dandv? |
0e977fa to
a4ed268
Compare
Contributor
Author
|
@bennetbo I've just added search for streaming results (with debounce), and did a final cleanup round. All yours! |
Adds a search bar to the agent panel, triggered by Ctrl+F (Cmd+F on macOS), that lets users grep the currently-loaded thread without leaving the agent panel. Custom bar rather than `BufferSearchBar` + `SearchableItem` because the agent panel is not a workspace `Item`, so the toolbar/`ItemHandle` plumbing those assume doesn't apply. The bar reuses: - `SearchQuery` for query parsing (regex / case / whole-word toggles). - `search::SearchOption::as_button` for the toggle button visuals — same buttons as `BufferSearchBar`. - `Markdown::set_search_highlights` / `set_active_search_highlight` for inline highlight rendering, exactly as `MarkdownPreviewView` uses them. Each visible per-entry markdown block in the active thread (user messages, assistant chunks, tool-call labels) is searched, and results are surfaced one match at a time via the next/prev controls. Activating a match jumps the `ListState` to the entry that owns it and asks the markdown to auto-scroll to the source index. Keybindings under the `AcpThreadSearchBar` context: - Linux and Windows: `alt-r` toggles regex, matching the wider `Pane` context convention for `search::ToggleRegex` on those platforms. - macOS: `alt-cmd-x` toggles regex. `alt-r` on macOS is reserved for the `®` character; chord shortcuts use `cmd+alt` instead. - Ctrl+F (Cmd+F on macOS) inside the bar dispatches `search::FocusSearch` (focus query + select all), mirroring how `BufferSearchBar` handles re-entry into an already-open bar. When dismissed, focus returns to the message editor (matching the pattern used by `cancel_editing` and `send_queued_message_at_index`) so the user can immediately keep typing. Out of scope for this initial version: - Searching `AssistantMessageChunk::Thought` blocks or any `ToolCallContent` (terminal command output, file content read by tools, diff editors, image previews). The matcher never walks `tool_call.content` and skips `Thought` chunks of assistant messages; expanding a tool call does NOT make its content searchable. Trade-off: the visible match count stays consistent with what the user sees on screen, at the cost of users not being able to grep tool output through this bar. - Searching tool-call raw input/output JSON, which is not a `Markdown` entity. - Searching across multiple threads.
Two integration tests in `conversation_view::tests` cover the matcher and bar lifecycle: - `test_thread_search_finds_matches_across_entries` drives a thread containing case-insensitive matches in user-message text and assistant-message chunks. Asserts the total match count, exercises next/prev cycling, and verifies the active match index updates correctly. - `test_thread_search_dismiss_clears_highlights` opens the bar with a query, dismisses it, and asserts no markdown is left holding a search highlight. Adds two `#[cfg(test)] pub(super)` accessors on `ThreadSearchBar` (`match_count` and `active_match_index`) so the tests can observe matcher state without exposing the private `ThreadMatch` struct more broadly. Also drops a redundant `focus_handle` clone in `nav_button`'s tooltip closure (the prior site was its final use).
Two UX fixes from manual testing of the in-thread search bar: * `track_focus` on the bar root so the `AcpThreadSearchBar` key context is in the focused editor's dispatch chain. Without this, Esc fell through to ancestor handlers (`menu::Cancel` which cancels agent generation, or the workspace `BufferSearchBar` dismiss). * Skip tool-call content; only search labels. Searching inside collapsed content produced large match counts with no visible highlights, which is user-hostile. Labels are always visible.
… blocks Round 2 of UX fixes from manual testing: * Esc actually closes the bar: contribute the `AcpThreadSearchBar` key context from `ThreadView` when the bar is visible, and register forwarding handlers (`DismissThreadSearch`, `SelectNext/PreviousThreadMatch`) on the same outer element. Mirrors the context-contribution pattern that lets `BufferSearchBar`'s Esc work despite no `track_focus` on its own element. * Cmd/Ctrl+F outside the bar focuses it instead of closing it. `toggle_search` now distinguishes visible-and-focused (close) from visible-and-unfocused (focus the bar). The close path is still Esc / the X button. * Show regex error message below the input. `build_query` now returns `(Option<query>, Option<error>)`; errors are rendered in a small red `Label` row beneath the bar, matching `MarkdownPreview` search. * Drop the conditional red border on the input. Both error states (bad regex and non-empty query with no matches) are now conveyed via red query text alone, via a new `in_error_state` flag passed to `render_query_input`. No border treatment in any state. * Skip `AssistantMessageChunk::Thought` in the matcher: same hidden-collapsed-content failure mode as tool-call content. Search only the visible `Message` chunks. Searching collapsed thinking output is not supported by this bar.
…ghts, action forwarding
Several fixes layered on top of the initial custom-bar implementation,
all confined to `agent_ui`:
- Forward `search::Toggle{CaseSensitive,WholeWord,Regex}` and
`search::FocusSearch` from `ThreadView` so they fire when the bar is
visible but focus is in the message editor. Without these the keymap
resolved the binding (because `AcpThreadSearchBar` is contributed at
the `ThreadView` level when the bar is visible) but the dispatched
action found no handler on the bubble path.
- Defer the bar's `on_activate_match` callback's `view.update` via
`cx.defer` to avoid re-entering `ThreadView`'s update from inside the
bar's `select_next_match`. Reproduced as a double-borrow panic
("cannot update X while it is already being updated") on Enter and
on Ctrl+F while the bar was open.
- Catch `editor::actions::Cancel` at the `ThreadView` level when the
bar is visible. The keymap binds `escape` to `editor::Cancel` at the
`Editor` context, which shadows `AcpThreadSearchBar`'s `escape ->
agent::DismissThreadSearch`. `Editor::cancel` propagates when there's
nothing to cancel locally; without the new handler, the propagated
`Cancel` walked up to `Workspace`, where `BufferSearchBar::register`
has a workspace-wide handler that dismissed the active pane's search
bar instead of ours.
- Highlight user-message search hits via
`Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)`
on the inner `Editor` backing each `MessageEditor`. Past user messages
are rendered through `MessageEditor`, not through the markdown
attached to the entry, so highlights painted on the markdown were
counted but invisible. Introduces a `MatchTarget::{Markdown, Editor}`
enum on `ThreadMatch` so active-vs-inactive re-paint dispatches to
the right entity; splits the bar's `highlighted` field into
`highlighted_markdowns` and `highlighted_editors` for clean clearing.
`collect_markdowns` no longer pulls the user message's markdown,
avoiding double-counting.
- Mute the zero-match counter color (was `Color::Error`; mirror MPS /
`BufferSearchBar`). Red feedback comes from the query text alone, not
also from the counter.
- Search placeholder: "Search thread…" → "Search this thread…" to make
the per-thread scope explicit. Addresses the "we'll need to think
about how to communicate this feature" line from the PR zed-industries#54816
rejection — the bar searches only the currently-loaded thread,
never history or cross-agent context.
- Three new gpui tests in `crates/agent_ui/src/conversation_view.rs`:
- `test_thread_search_select_next_from_thread_view_update_does_not_panic`
drives `select_next_match` from inside a `ThreadView::update_in`
closure, reproducing the action-dispatch nesting that motivated
the `cx.defer` fix.
- `test_thread_search_editor_cancel_dismisses_bar` dispatches
`editor::actions::Cancel` while the bar is visible and asserts the
bar is dismissed before propagation reaches the workspace.
- `test_thread_search_highlights_user_message_editor` searches a
query that only matches the user message and asserts the user
message's inner `Editor` carries `BufferSearchHighlights` after
the matcher runs, and that `clear_highlights` removes them.
- Promote `MessageEditor::editor()` from `#[cfg(test)] pub(crate)` to
always-`pub(crate)` so the search bar can paint highlights on the
inner `Editor` outside tests. Kept the accessor narrow (crate-local)
and documented the contract.
Release Notes:
- Added in-thread search for the agent panel (Ctrl/Cmd+F). Searches the
currently-loaded thread only; not cross-thread or cross-agent.
The bar binds `shift-enter` → `agent::SelectPreviousThreadMatch` under
the `AcpThreadSearchBar` context. Base keymaps that bind `shift-enter`
at the bare `Editor` context — notably JetBrains, which maps it to
`editor::NewlineBelow` — shadow the bar's binding because both
predicates match the focus chain at the same depth and gpui's
binding-index tiebreak favors the later-loaded base keymap. Result:
pressing Shift+Enter in the query input inserts a newline (rendered as
a visible `\n` glyph in the single-line editor) instead of navigating
to the previous match.
An `AcpThreadSearchBar > Editor` keymap block (the pattern
`BufferSearchBar && !in_replace > Editor` uses for the workspace buffer
search bar) does NOT win either: it also matches at the same depth and
still loses to the base keymap on the load-order tiebreak. The bar's
binding only wins when no base keymap claims `shift-enter` at the
`Editor` context.
Fix by capturing `editor::Newline*` actions on the bar's `bar_row`
element in the capture phase and routing them to `select_prev_match`,
calling `cx.stop_propagation()` to prevent the editor's bubble-phase
handler from inserting a newline into the single-line query buffer.
This is the same pattern `BufferSearchBar`, `MessageEditor`, and the
inline-assist prompt editor use for the same class of conflict.
Also adds a regression test that loads `default-linux.json` plus
`linux/jetbrains.json`, then asserts
`cx.simulate_keystrokes("shift-enter")` navigates without inserting a
newline into the query buffer.
The `ContextCompaction` variant of `AgentThreadEntry` was added on the base branch, but the exhaustive `match` in `collect_markdowns` was not updated during the merge, breaking the build. It carries no searchable markdown content, so handle it as a no-op like `CompletedPlan`.
user messages - Debounce the match rescan (150ms) so fast typing and streaming message chunks don't trigger a full synchronous scan per event. - Subscribe to AcpThread updates (NewEntry / EntryUpdated / EntriesRemoved) so matches, highlights, and the counter track a streaming conversation without re-touching the query. Gated on an `is_active` flag and cancelled on hide so a hidden bar never re-applies highlights behind closed search UI. - Navigate the list to the entry that owns the active match (the same path `scroll_to_most_recent_user_prompt` uses), and select the match range in past user messages with `no_scroll` so the active highlight tracks it. Cross-entry scrolling brings the message's top into view. Known limitation: a match below the fold of a very long user message stays highlighted but may remain off-screen, because an AutoHeight editor inside a virtualized List can't reliably drive intra-entry autoscroll (markdown matches don't share this, as the markdown element re-issues its autoscroll request every paint). Most user messages are shorter than a viewport, so this is left unaddressed by design. - Replace `let _ = view.update(...)` with `.ok()` per repo error- handling rules. - Drop the vestigial source_index callback param; share focus_query_and_select_all between focus_and_refresh and focus_search; remove the dead `let _ = tool_call.content`; fix the stale `matches` doc comment; note the O(matches) per-step editor repaint. - Add regression tests: one that streams a new entry while search is open and asserts the subscription refreshes the match count, and one that asserts the list scrolls to the user-message entry owning a match.
a4ed268 to
3fb0448
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This is a narrower alternative to #54816, scoped to search only the currently-loaded thread, excluding tool output or thinking blocks (happy to follow up on those, see next). It uses a custom bar confined to
agent_uirather thanBufferSearchBar+SearchableItem, avoiding the cross-crate plumbing that #54816 reached. Open as draft pending direction from @benbrandt on what scope/approach would be acceptable for in-thread search.What this PR does
Adds a search bar to the agent panel, triggered by Ctrl+F (Cmd+F on macOS), that lets users grep the currently-loaded thread without leaving the agent panel; not cross-thread or cross-agent.
Markdown::set_search_highlightsfor markdown-rendered content andEditor::highlight_background(HighlightKey::BufferSearchHighlights, …)for past user messages (rendered throughMessageEditor's innerEditor, not through markdown).BufferSearchBar).Commits (authored by Claude 4.7 Opus, max)
Seven logical commits
agent_ui: Add in-thread search bar— initial implementation: bar UI, keymap bindings underAcpThreadSearchBarcontext, markdown highlight plumbing, focus-restore on dismiss.agent_ui: Add unit tests for in-thread search— coverage of the matcher across entry kinds and the dismiss-clears-highlights path.agent_ui: Limit search to visible tool-call text— UX fixes from manual testing:track_focussoAcpThreadSearchBarcontext lands in the editor's dispatch chain; red border on zero-match query; skip tool-call content (only search labels).agent_ui: Fix Esc dispatch, smart toggle, error message, skip Thought blocks— round 2 of UX fixes: contributeAcpThreadSearchBarcontext fromThreadViewwhen bar is visible, smart Ctrl/Cmd+F outside-the-bar focuses instead of closing, regex error message row, skipAssistantMessageChunk::Thought.agent_ui: Polish thread search bar — Esc routing, user-message highlights, action forwarding—search::*action forwarders onThreadView;cx.deferaround the activate callback (fixes a double-borrow panic);editor::actions::Cancelinterception so Esc dismisses our bar instead of escaping to the workspace'sBufferSearchBar; user-message highlights via the innerEditor; muted zero-match counter; three new gpui regression tests.** — capture-phase intercept ofeditor::Newlineon the bar'sbar_rowelement so a base keymap bindingshift-enterat theEditorcontext (e.g. JetBrains →editor::NewlineBelow) can't shadow the bar'sagent::SelectPreviousThreadMatch. Adds a regression test that loadsdefault-linux.json+linux/jetbrains.jsonand assertsshift-enter` navigates instead of inserting a newline.agent_ui: Debounce thread search, refresh on thread changes, highlight user messages** — last round before maintainer review: 150 ms debounce on the match rescan; subscribe toAcpThreadupdates so results/highlights/counter follow a streaming conversation live; navigate the list to the entry owning the active match;.ok()instead oflet _ =; assorted cleanups; two new regression tests (test_thread_search_refreshes_on_new_thread_entry,test_thread_search_scrolls_to_later_user_message_match).8 gpui tests cover the load-bearing logic (
cargo test -p agent_ui --lib -- thread_search). All pass.Manual testing
Verified on Linux against
upstream/main13e7c11768(fullreleaseprofile, with LTO andcodegen-units=1built and tested at that commit). Branch since merged withupstream/maina6780a5. Of the 100 intervening upstream commits, several touch files in this diff; one produced a real conflict incrates/agent_ui/src/conversation_view.rs(gpui::{...}import block — both sides added new, non-overlapping symbols; resolved by union).Bar opens / dismisses via Ctrl+F and Esc
Next/prev navigation via Enter / Shift+Enter / F3 / Shift+F3 / chevron buttons
Case / whole-word / regex toggles via buttons and via Alt+C / Alt+W / Alt+R (Linux)
Highlights inside past user messages render correctly on the
MessageEditor's innerEditorquery text turns red on no-match; bad regex shows error message; zero-match counter stays muted (not red)
search::*actions fire from outside the bar (focus in message editor) via theThreadView-level forwardersWorkspace pane
BufferSearchBaris unaffected; the two bars hold independent stateFeature looks great in light mode and dark mode, and with various themes
Navigating to a match in a past user message scrolls that message into view (its top to the viewport top)
Results update live as the agent streams new messages while the bar is open (debounced ~150 ms, same for typing)
Zed.agent.thread.search.subscribe.to.thread.updates.webm
Full manual test plan
Setup (preconditions for every test below unless otherwise noted)
./target/release-fast/zed --user-data-dir ~/.local/share/zed-dev-featwatermelon)Core matching
T-001 — Ctrl+F opens the bar with focus in query
Status: ✅ PASS 2026-05-15 15:30
Repro: With focus in the agent panel's message editor, press Ctrl+F (Linux) / Cmd+F (macOS). The search bar appears at the top of the thread view and the query input is focused.
T-002a — Active match visually distinct from inactive matches
Status: ✅ PASS 2026-05-15 15:30
Repro: Type a query that produces ≥3 matches. The current ("active") match must be visually different from the others — different highlight color, not just position. If they look identical, this may be a theme issue (
search_active_match_backgroundvssearch_match_backgroundtoo close on the entry's background); note the theme.T-002b — User-prompt text gets inline highlight, not just match count
Status: ✅ PASS 2026-05-15 17:15 (fix shipped 2026-05-15 16:15; regression-guarded by
test_thread_search_highlights_user_message_editor)Repro: Send a user prompt containing a distinctive substring. Then search that substring. The user prompt text must show yellow highlight, not just be counted. The bar's matcher reads from
message.content.markdown()but the on-screen render goes through aMessageEditor; the current code only highlights viaMarkdown::set_search_highlights, which misses the editor.Notes: Fix routes user-message matches through
Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)— the same pathEditor's ownSearchableItemimpl uses.collect_markdownsno longer pulls the user message's markdown (avoiding double-counting). The bar now maintains separatehighlighted_markdownsandhighlighted_editorslists for clean-up. Match-target enum (MatchTarget::MarkdownvsMatchTarget::Editor) tags each match so active-vs-inactive re-paint can dispatch correctly. Pending runtime verification on nextrelease-fastbuild.T-003 — Enter / Shift+Enter in bar navigates matches
Status: ✅ PASS 2026-05-25 14:00 (verified on
releasebuild)Repro: With focus in the query, type a query with ≥3 matches. Press Enter → counter
1/N → 2/N → 3/N. Press Shift+Enter → reverses (and no\ns are output in the search box). F3 / Shift+F3 same.Option toggles
T-004 — Alt+C toggles case sensitivity from inside bar
Status: ✅ PASS 2026-05-15 07:50
Repro: With focus in query, press Alt+C.
Aabutton toggles state; results re-filter.T-005 — Alt+W toggles whole-word from inside bar
Status: ✅ PASS 2026-05-15 15:30
Repro: Same as T-004, with Alt+W toggling
wdbutton.T-006 — Alt+R toggles regex from inside bar (Linux)
Status: ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:35)
Repro: Press Alt+R.
.*button toggles.Notes: macOS keymap (
alt-cmd-x) left unchanged in this session — it matches the wider macOS Zed convention.T-006a — Tooltips on toggle buttons show their hotkey
Status: ✅ PASS 2026-05-15 15:30
Repro: Hover each toggle button (
Aa,wd,.*). Tooltip shows action name AND keybinding (e.g. "Toggle Case Sensitive · Alt+C").Error / empty states
T-007 — Empty matches: no red border on bar input
Status: ✅ PASS 2026-05-15 15:30
Repro: Type
zzzzzzz. Query text turns red. Counter shows0/0. Bar input border stays neutral, no red box.T-008 — Bad-regex error message
Status: ✅ PASS 2026-05-15 15:30 (error renders aligned with the input)
Repro: Switch to regex mode, type
[. Error message appears below bar, aligned with the input.T-019 — Zero-match counter not colored red
Status: ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30)
Repro: Type a query with no matches. The counter (
0/0) stays muted, not red. MPS-parity.Dismissal & re-entry
T-009 — Esc doesn't interrupt agent generation
Status: ✅ PASS 2026-05-15 15:30
Repro: Start a long prompt; while the agent is generating, open the search bar and press Esc. Bar closes, generation continues.
T-010 — Close-X button position
Status: ✅ PASS 2026-05-15 15:30
Repro: Look at the bar. Close (X) button is on the right side, after the nav arrows (
<>1/NX). NOT free-floating left of the input.T-011 — Ctrl+F in bar selects all query text
Status: ✅ PASS 2026-05-15 15:30
Repro: With bar open and query containing text, press Ctrl+F. All query text becomes selected (next keystroke replaces).
T-012 — Ctrl+F outside the bar (bar already open) does not crash
Status: ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30; regression-guarded by
test_thread_search_select_next_from_thread_view_update_does_not_panic)Repro: Bar visible, focus in the message editor (not the bar). Press Ctrl+F. Bar gets re-focused, query text is selected. Must not crash.
Notes: Original crash also reproducible from Enter / Shift+Enter inside the bar after a search had matches. Fix wraps the
on_activate_matchcallback'sview.updateincx.defer.T-021 — Esc dismisses agent bar (not the unrelated workspace pane's BufferSearchBar)
Status: ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 14:40; regression-guarded by
test_thread_search_editor_cancel_dismisses_bar)Repro: Open a file in a workspace pane editor (e.g.
settings.json). Open BufferSearchBar there. Switch focus to the agent panel, open agent search bar, type a query. Press Esc. The agent bar must dismiss; the workspace pane's BufferSearchBar must remain.Notes: Root cause:
Editor::cancelin single-line mode callscx.propagate(). The propagatededitor::actions::Cancelwalked past our bar all the way toWorkspace, whereBufferSearchBar::registerhad registered a workspace-wide handler that dismissed the active pane's bar. Fix:ThreadViewnow catcheseditor::actions::Cancelwhen the bar is visible.Action routing while bar is open, focus is in the message editor
T-013 — F3 / Shift+F3 from outside the bar
Status: ✅ PASS 2026-05-15 15:30 (Enter from outside is expected not to work — message editor's
enterbinding outranks. F3 is the canonical out-of-bar nav key.)Repro: Bar open with matches, focus in message editor. Press F3 → next match. Shift+F3 → previous.
T-014 — Alt+C / Alt+W / Alt+R from outside the bar
Status: ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 02:30;
ThreadViewforwarders forsearch::ToggleCaseSensitive,ToggleWholeWord,ToggleRegex,FocusSearch)Repro: Bar visible, focus in message editor. Alt+C/W/R toggles the bar's options and re-runs search.
Nav buttons
T-022 —
</>chevron buttons in the bar advance matchStatus: ✅ PASS 2026-05-15 15:30
Repro: With ≥2 matches, click
<→ previous. Click>→ next. Wraps at ends.Coexistence with workspace-pane buffer search
T-015 — Ctrl+F in a workspace-pane editor still opens
BufferSearchBar(no agent-panel takeover)Status: ✅ PASS 2026-05-15 15:30
Repro: Focus a code editor in a workspace pane, press Ctrl+F. The pane's
BufferSearchBaropens as before; agent panel's bar does NOT open.T-016 — Independent bars: agent vs workspace pane
Status: ✅ PASS 2026-05-15 15:30
Repro: Have both bars open simultaneously. They hold independent state (different queries, different toggles, independent dismissal).
Tool-call content (auto-expand on match)
T-017 — Auto-expand collapsed tool calls on match
Status: ⏸️ BLOCKED (not implemented; out of scope for current session)
Repro: Have a tool call whose collapsed content contains a unique substring. Search that substring. The tool call auto-expands so the match is visible. After dismissal, the tool call collapses again unless the user manually expanded it before.
T-018 — Auto-expand collapsed Thinking blocks on match
Status: ⏸️ BLOCKED (not implemented; out of scope for current session)
Repro: Same shape as T-017 for a collapsed Thinking block.
T-019 — Streaming results automatically highlighted / live thread search
Status: ✅ PASS 2026-06-08
Repro: Send prompt "Write a 5-paragraph story about a researcher who hated noise. The last paragraph should be a one-sentence: "So she moved to " (replace that with the actual name)", then search for
Antarctica.Known limitations
crates/markdown's render layer - see issue markdown: search highlights in table cells are mispositioned within a single line, for columns 2..N #57229AutoHeightEditorinside a virtualizedList, which can't reliably drive intra-entry autoscroll the way markdown content does. User messages are usually shorter than a viewport, so this is left unaddressed.Self-Review Checklist:
unsafeintroduced; no network, file-system, or process APIs touched; only added dep issearch(promoted from dev-dep to runtime), already used by this crate's tests;MessageEditor::editor()accessor widening ispub(crate)(in-crate only). Assessment: no new attack surface.AcpThreadSearchBarcontext bindings) but I only verified Linux at runtime.Partially closes #39338
Release Notes: