Skip to content

text_finder: Seed last query and filters to make quick edits easier - #59849

Merged
yara-blue merged 9 commits into
zed-industries:mainfrom
ozacod:feat/restore-closed-picker
Jul 1, 2026
Merged

text_finder: Seed last query and filters to make quick edits easier#59849
yara-blue merged 9 commits into
zed-industries:mainfrom
ozacod:feat/restore-closed-picker

Conversation

@ozacod

@ozacod ozacod commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

It is incremental step to solve issue #59825.

This PR addresses the need for facilitating quick edits for matches obtained by ‘text_finder’. This makes the text finder remember the last query, so you can jump to a match, make a quick edit, and reopen the finder to the same results instead of typing the same query again.


Problem

A common flow is, open the text editor, then jump to first match, edit that file, then reopen the finder to continue for next matches. But on the reopen, the query was seeded from under the cursor. And after editing, the cursor is usually sitting on an unrelated word, and previous search was lost. The root cause is priority, the word under the cursor was seeding the query. 



Solution


Reorder query seeding so last query outranks the cursor word, then cursor word can be dropped entirely, since last query is prioritized over the word under cursor, the last query always wins, so checking the cursor word afterwards is dead code. And JetBrains makes the same choice, entirely ignores word on the cursor for seeding query. Explicit selection still outranks the last query, since selecting text is usually a deliberate choice.

Before

1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text or word under the cursor
4- Empty



After

1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text
4- Last query (of this project)
5- Empty



With updated order, this friction disappears (the same order is also observed in JetBrains). To make the last query persistent, it is stored per project in the database along with the active filters (case sensitive, whole word, regex), so they also survive reopening the project.

Testing

  • Manually verified the seed priority order between the options.
  • Verified the last query is seeded when project is reopened.
  • Verified filters are restored regardless of this query order.

Release Notes:

  • Improved the text finder to seed the last query and filters to make quick edits easier.

ozacod and others added 4 commits June 24, 2026 18:45
…arch (zed-industries#59779)

## Summary

When opening the text finder (`text_finder::Toggle`), pre-populate its
query the same way project search already seeds itself. Previously
`seed_query` only asked the active editor for the word under the cursor,
so opening the text finder from a project search tab or a focused buffer
search bar started empty.

`seed_query` now tries these sources in priority order:

1. **Active project search** — its current query
(`ProjectSearchView::search_query_text`).
2. **Focused buffer search bar** — its query, reusing project search's
existing `buffer_search_query` helper (promoted from private to
`pub(crate)` so there's one source of truth rather than a copy).
3. **Word under the cursor** — the existing `query_suggestion` fallback,
still honoring the `seed_search_query_from_cursor` setting.

This mirrors how project search is fed from the buffer search bar
(`existing_or_new_search`), keeping the seeding behavior consistent
across the three search surfaces.

## Testing

- Manual: open project search with a query → toggle text finder → query
carries over; cmd+f with a query focused → toggle text finder → query
carries over; otherwise the word under the cursor seeds it as before.

Release Notes:

- Improved text finder to pre-fill its query from the active project
search or buffer search

---------

Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
@cla-bot cla-bot Bot added the cla-signed The user has signed the Contributor License Agreement label Jun 24, 2026
@yara-blue yara-blue self-assigned this Jun 25, 2026
@yara-blue

Copy link
Copy Markdown
Contributor

Good idea! Taking it one step further I've added #59895, though that does not exclude this.

Note: Entries per project are never deleted even when a project is removed. Since each one is a small string, growth should be negligible and is not handled here.

mhmmm this seems fine, feels off though :) I'll see if I can think of anything.

@ozacod

ozacod commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

Good idea! Taking it one step further I've added #59895, though that does not exclude this.

Note: Entries per project are never deleted even when a project is removed. Since each one is a small string, growth should be negligible and is not handled here.

mhmmm this seems fine, feels off though :) I'll see if I can think of anything.

Now it uses workspace table instead of using shared database. It is already existing pattern for bookmarks which is also persistent after project is reopened.

@ozacod
ozacod marked this pull request as draft June 25, 2026 12:22
@ozacod
ozacod force-pushed the feat/restore-closed-picker branch from 5b37baa to 4d6c924 Compare June 25, 2026 12:25
@ozacod
ozacod force-pushed the feat/restore-closed-picker branch from 6368e8c to 1794879 Compare June 25, 2026 12:44
@ozacod ozacod changed the title text_finder: Seed last query to make quick edits easier text_finder: Seed last query and filters to make quick edits easier Jun 25, 2026
Comment thread crates/search/src/text_finder.rs Outdated
/// item in priority order, mirroring how project search seeds itself: an
/// active project search's query, then a focused buffer search bar's query,
/// then the word under the cursor (honoring `seed_search_query_from_cursor`).
/// The query to pre-populate the text finder with, sourced in priority order:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather a long doc comment (the function itself is not hard to read). Might be replaced with something like: "Guess the query the user probably wants for pre-populating the search input"

@yara-blue yara-blue added the area:pickers Everything related to pickers that are in a modal label Jun 25, 2026
@yara-blue

Copy link
Copy Markdown
Contributor

I've been thinking about this, it might be better to pivot this to a query history system and look into restoring the entire picker. That restoring would not work through persistence, we would just not "close" the picker fully. We'd hide it. Would that cover your use case?

@ozacod

ozacod commented Jun 25, 2026

Copy link
Copy Markdown
Contributor Author

After this PR is merged, I was planning to add a history system by keeping the latest 10–20 queries in the database, like we did for the last one, then seeding history[0] into the search query. The user would then be able to go through the history with option+arrow keys.

It would be a relatively complex PR, since not everything searched should be fed to history (the live-search problem). Debouncing isn't a good idea either, since the time interval would have to be determined heuristically; instead we'd
look at other signals (dismissing the window, switching search matches, etc.).It would also provide persistence across project reopen.

Restore (#59825) could also be defined as a separate action with its own keybinding, so both could be active at the same time. It wouldn't be fully redundant, since restore could also bring back scroll and selection state, not just the query. But the two would still overlap on the query part, so having both might feel like two similar ways to do the same thing. I'd leave that decision to the team. I'm open to closing this PR depending on the design decision.

Restore also touches the dismiss path: depending on whether we retain the picker (and decide when to actually drop it) or fully close it and rebuild from a saved snapshot, so it's a bigger change than the history part.

Personally, I'd lean toward making the preview editable instead that removes the round-trip entirely, since you could fix the typo in place without ever reopening. It's an alternative to the restore flow rather than to query history, though. I saw it was already raised in #59825 and the team leaned toward the restorable picker over it, so I assume it's off the table, just noting my preference.

@ozacod
ozacod marked this pull request as ready for review June 25, 2026 15:58
@yara-blue

Copy link
Copy Markdown
Contributor

I gotta run and get started on dinner but before I go I wanted to share the prototype we build for restoring the last picker: #59912

I'll try and get that in the right shape tomorrow.

It would be a relatively complex PR, since not everything searched should be fed to history (the live-search problem).

Good point! Still would be amazing to have, especially for regexes.

I saw it was already raised in #59825 and the team leaned toward the restorable picker over it, so I assume it's off the table, just noting my preference.

I'd love you're input on this after landing the restorable picker. Similarly I'd want to try it for a bit to see how it feels. The same is true for this PR. This might still be useful even with the restorable picker. I gotta think and confer with some collegues about that.

As a stepping stone to a full history it's already great. Could always put it behind an arrow up press. Anyway I hope to get back to this tomorrow, if I don't feel free to ping me!

@smitbarmase smitbarmase added area:search buffer search, project search, etc and removed area:pickers Everything related to pickers that are in a modal labels Jun 29, 2026
@ozacod

ozacod commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Hi @yara-blue,
I think it is still relevant after #59912 landed, luckily it is still mergeable without any conflict.

@yara-blue
yara-blue added this pull request to the merge queue Jul 1, 2026
@yara-blue

Copy link
Copy Markdown
Contributor

Hi @yara-blue,
I think it is still relevant after #59912 landed, luckily it is still mergeable without any conflict.

Then let's get this merged 👍

Merged via the queue into zed-industries:main with commit e4e2c9d Jul 1, 2026
46 checks passed
@ozacod
ozacod deleted the feat/restore-closed-picker branch July 1, 2026 10:49
@iggyzuk iggyzuk mentioned this pull request Jul 1, 2026
1 task
@iggyzuk

iggyzuk commented Jul 1, 2026

Copy link
Copy Markdown

Great work. I think it might be a good idea to have the last query be configurable. I would like to disable it because my workflow is to always search for the word that is under the cursor.

@yara-blue

Copy link
Copy Markdown
Contributor

Great work. I think it might be a good idea to have the last query be configurable. I would like to disable it because my workflow is to always search for the word that is under the cursor.

Pr's are welcome! Zed used to have a setting for the size of the file finder, I think we can have a pickers setting category. Might be useful when the LSP pickers land too. (Could have something like use pickers over multibuffers for lsp requests).

@yara-blue yara-blue removed their assignment Aug 3, 2026
jolutz pushed a commit to jolutz/zed that referenced this pull request Aug 8, 2026
…ed-industries#59849)

## Summary

It is incremental step to solve issue zed-industries#59825.

This PR addresses the need for facilitating quick edits for matches
obtained by ‘text_finder’. This makes the text finder remember the last
query, so you can jump to a match, make a quick edit, and reopen the
finder to the same results instead of typing the same query again.


## Problem

A common flow is, open the text editor, then jump to first match, edit
that file, then reopen the finder to continue for next matches. But on
the reopen, the query was seeded from under the cursor. And after
editing, the cursor is usually sitting on an unrelated word, and
previous search was lost. The root cause is priority, the word under the
cursor was seeding the query. 



## Solution

Reorder query seeding so last query outranks the cursor word, then
cursor word can be dropped entirely, since last query is prioritized
over the word under cursor, the last query always wins, so checking the
cursor word afterwards is dead code. And JetBrains makes the same
choice, entirely ignores word on the cursor for seeding query. Explicit
selection still outranks the last query, since selecting text is usually
a deliberate choice.

### Before

1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text or word under the cursor
4- Empty



### After
1- Active project search query (if any)
2- Active buffer search query (if any)
3- Selected text
4- Last query (of this project)
5- Empty



With updated order, this friction disappears (the same order is also
observed in JetBrains). To make the last query persistent, it is stored
per project in the database along with the active filters (case
sensitive, whole word, regex), so they also survive reopening the
project.


## Testing

- Manually verified the seed priority order between the options. 
- Verified the last query is seeded when project is reopened.
- Verified filters are restored regardless of this query order.

Release Notes:

- Improved the text finder to seed the last query and filters to make
quick edits easier.

---------

Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:search buffer search, project search, etc cla-signed The user has signed the Contributor License Agreement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants