input: Expose editor search API - #2533
Conversation
The search state and the public search API this branch introduced were implemented on main in the meantime (longbridge#2691, longbridge#2716, longbridge#2932, longbridge#2953, longbridge#2955, longbridge#3013), so the conflicting files take main's version. The example and the documentation are ported to the new API in follow-up commits.
Main already exposes the search engine on the editor state, but two things still tied it to the built-in panel. Match highlights were painted only while `search_session.open`, which also shows the panel, so a query set through `set_search_query` counted matches the editor never showed. And an editor that is not `searchable` swallowed `Search` and `Replace` without propagating them, so a parent could not bind `Ctrl-F` to its own field. `SearchSession` now tracks `active` separately from `open`: opening the panel or setting a query activates the session, `close_search` ends it, and the element highlights while it is active. The two action handlers propagate when the editor is not searchable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Ports the custom search example from the branch to the `examples/` package layout and the `EditorState` API, and documents the custom search UI in the Editor guide, in English and Chinese. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
3e61573 to
049f7bf
Compare
|
Thanks for the PR, and sorry it sat for so long. I've merged Two things this PR wanted were still missing on
Implementation in these commits was AI-generated and reviewed. 🤖 Generated with Claude Code |
Icon-only buttons carry a tooltip, as the Design Guides ask. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Code reviewNo issues found. Checked for bugs and CLAUDE.md compliance. 🤖 Generated with Claude Code |
32593ff to
7f43c58
Compare
…able` `SearchMatcher::current` reports the current match as `Option<usize>`, so "no match" is not mistaken for the first one; `current_match_index` stays. `SearchSession` is `#[non_exhaustive]`, since it gains fields; build it with `Default`. And `searchable` is documented for what it gates — the built-in panel and its shortcut, not the search API — instead of hidden. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7f43c58 to
5c87859
Compare
The Editor guide's custom search section shows the whole path already. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Description
An application that wants its own search UI on the editor — keeping the editor's matching, highlighting, scrolling and replacing, but drawing the search bar itself — had no supported way to do it: search could only be switched on or off with
.searchable(true), and everything else lived inside the built-inSearchPanel.Since this PR was opened, the engine moved into
gpui-baseand its API became public on the editor state (#2691, #2716, #2932, #2953, #2955, #3013):set_search_query,close_search,next_search_match,previous_search_match, the replace methods andsearch_session(). This PR, rebased onto that, closes the gaps that still tied a search to the built-in panel and documents the custom-UI path.Highlights without the panel
Match highlights were painted only while
search_session.open, which also shows the panel, so a query set throughset_search_querycounted matches the editor never showed.SearchSessionnow tracksactiveseparately fromopen: opening the panel or setting a query activates the session,close_searchends it, and the element highlights while it is active. The panel keeps keying its own visibility onopen.SearchSessionis#[non_exhaustive], since it gains fields; build it withDefault.The shortcut reaches the application
An editor that is not
searchableswallowedSearchandReplaceinstead of propagating them, so a parent view could not bindCtrl-F/Cmd-Fto its own field. Both handlers nowcx.propagate()when the editor is not searchable.searchableis no longer#[doc(hidden)]and is documented for what it gates: the built-in panel and its shortcut, not the search API.current()SearchMatcher::current()reports the current match asOption<usize>, so "no match" is not mistaken for the first one;current_match_index()stays.Docs
The Editor guide gains a "Custom search UI" section, in English and Chinese:
set_search_queryfrom the application's own field, navigating and describing the matches, replacing, ending withclose_search, and takingCtrl-F/Cmd-Fon the view that owns the field.Breaking Changes
None.
SearchSessionis now#[non_exhaustive], so it must be built withDefaultrather than a struct literal; no code in this repository or its examples did otherwise.How to Test
cargo test -p gpui-base -p gpui-component --lib -- search: covers the session staying active afterset_search_querywithout the panel, the shortcut reaching a host view when the editor is not searchable and opening the panel when it is, and the match label/current()semantics.cargo run -p example-editor: the built-in panel behaves as before, including resuming its last query on reopen.The rebase, the Base changes and the documentation were written with Claude Code and reviewed by hand; the original API proposal is by @calmondev.