ac94de78ab696fc897b82de467490c1a57e72a6d
866
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
77d716d5ce |
Keep first match selecting during type on search (#63375)
Follow-up to https://github.com/zed-industries/zed/pull/62506 Before: https://github.com/user-attachments/assets/19f6f0df-c5e3-417e-a351-13a09ccb726b After: https://github.com/user-attachments/assets/0b302ed7-a98d-4db4-81bc-d67f5cc7db87 * Fixes type on search not selecting the very first result as the regular search does. * Unifies the flicker freezing state better in the editor Release Notes: - N/A |
||
|
|
34c48d6579 |
Fix project search holding a reference to closed unsaved files (#61677)
# Objective Fixes #28398 ## Solution This issue was occurring because `ProjectSearch` stored `Entity<MultiBuffer>` with has reference counted pointers to underlying buffers The function `remove_deleted_buffers` is renamed to `remove_stale_buffers` and it now also checks for buffers which do not have a file associated with them and are closed. Then, it removes them from `Entity<MultiBuffer>` stored in ProjectSearch. This function is also called in again when workspace is upgraded. ## Testing Bug being fixed was manually verified. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed project search retaining results from closed untitled buffers. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
28c7f0cd8e |
Enable project search on type by default (#62506)
Closes https://github.com/zed-industries/zed/issues/9318 Most of the diff is tests. Notable behavior changes during this mode, compared to current mode: * unsaved changes in multi buffer won't spawn any "save or not" pop-ups during typing — submitting the query still does it, as before. Unsaved files will stay so after being sorted out on typing: we cannot save them by default as file-less buffers need a save modal; Zed should already be able to persist and restore such changes on restart. * gutter may jump during search, if new excerpts with large line numbers appear during query input — yet it would not shrink back to avoid excessive flickering and rewraps Release Notes: - Enabled project search on type by default (use `{ "search": { "search_on_type": false } }` to restore the previous behavior) |
||
|
|
570d9095a7 |
Use Duration to improve type safety and unit correctness (#62969)
# Objective - Prefer using `Duration` instead of integers when dealing with spans of time. This prevents confusing different units of time and comparing arbitrary integers with durations. - Remove `_ms`/`_secs` suffixes from variables which are `Duration`, since their unit is inside of the type. - Initialize large integer constants using `Duration`, which has more descriptive constructors, while maintaining the resulting integer type. Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
255880598d |
Switch from cargo-machete to cargo-shear (#62643)
This results in ~110 crates being removed, and some orphaned files also. --- Release Notes: - N/A Signed-off-by: Neel <neel@zed.dev> |
||
|
|
d5da3168c0 |
search: Fix regex replace with lookahead and lookbehind (#61900)
# Objective - Fixes #25905 - Regex search-and-replace silently does nothing when a same-line pattern contains a lookahead or lookbehind. Searching highlights the correct hits, but Replace All or `:s` in Vim mode leaves the buffer untouched. Reproduce with `316227766016837933199`, search `(\d)(?=(\d{4})+$)` in regex mode, and replace with `$1,`. Expected: `3,1622,7766,0168,3793,3199`. Actual before this change: nothing changes. The same problem affects `(?<=foo: )bar` replaced with `BAZ`. `SearchQuery::replacement_for` expanded the replacement by re-running the whole pattern against the matched text alone. Lookaround assertions inspect text outside the match, so the isolated hit no longer matched and the edit replaced the hit with itself. ## Solution - `replacement_for` now expands from captures located at the exact hit range within its source context. - Single-line regex hits use the complete source line, so lookahead, lookbehind, and line anchors see the same surrounding text used by search. - Literal and escaped-regex searches bypass context reconstruction because their replacements do not use captures. - Multi-line hits retain the exact matched text, preserving the prior cross-line behavior. - If selection boundaries prevent the pattern from matching the reconstructed line, replacement falls back to the isolated hit, preserving prior behavior. - Replace All caches the source line across hits on the same line. Cross-line lookaround remains unchanged: assertions that need text outside a multi-line hit still produce a no-op replacement. Search-within-selection can also retain the prior no-op behavior when the selection boundary changes assertion context. ## Testing - `cargo test -p search test_replace_with_lookaround` (2 passed) - `cargo fmt --all -- --check` - `./script/clippy -p editor -p project -p search` - Tested on Linux arm64. The change is platform independent. ## Self-Review Checklist: - [x] I have reviewed the diff for quality, security, and reliability - [x] Unsafe blocks, if any, have justifying comments - [x] The content adheres to Zed UI standards - [x] Tests cover the changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed same-line regex replacements that use lookahead or lookbehind |
||
|
|
0d952edd5a |
text_finder: Highlight the query as a regex when the regex filter is on (#61128)
the buffer search and project search bars both already load the `regex` language and put it on their query buffer when the regex filter is on. the text finder never got that, so a regex you type in there is just plain text. did the same thing here. the only slightly annoying part was that the picker's head editor is `pub(crate)`, so text_finder couldn't get at it. added a small `query_editor()` accessor to `Picker` for that. `adjust_query_regex_language` mirrors the two existing ones. test asserts the query buffer's language is regex with the filter on, and gone once it's off. Closes #59945. Release Notes: - Improved the text finder by highlighting the query as a regex when the regex filter is on --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
ff50948537 |
deps: Bump pathfinder_simd & fix upcoming rustc warnings (#62170)
While building Zed with nightly rustc I've noticed it doesn't compile because of good old pathfinder_simd. It also emits a bunch of warnings about use of f64 literals where f32 is expected, so I've fixed them - it should make future upgrades more straightforward. |
||
|
|
01961bef59 |
Speed up cargo build -p zed compilation (#62059)
Splits the crate graph.
Before, the compilation graph: `editor → picker_preview → search →
project_panel → open_path_prompt → recent_projects → title_bar →
collab_ui → zed`
After, the compilation graph: `editor → picker_preview → search →
agent_ui → sidebar → zed`
With sccache disabled and project fully built, `touch
crates/editor/src/editor.rs` and `cargo build -p zed` took time
Before (
|
||
|
|
5c6dbc3ab2 |
solo_diff_view: Hide multibuffer controls in solo diffs (#61998)
# Objective Remove the redundant expand/collapse-all-files control from solo diff views. A solo diff represents one file, so the multibuffer-wide control is not applicable and duplicates the per-file full-file/changes-only toggle. ## Solution Treat searchable items that intentionally hide their underlying splittable editor as ineligible for the generic multibuffer expand/collapse control. This keeps search bound to the focused side of a split diff while preserving the existing expand/collapse controls in Project Diff, Branch Diff, staged/unstaged diffs, Commit View, and other regular multibuffer views. ## Testing - `cargo -q test -p search test_uses_primary_left_when_in_multi_buffer -- --nocapture` - `cargo -q test -p search buffer_search -- --nocapture` (26 passed) - `git diff --check` - Manually verified the solo diff no longer shows the expand/collapse-all-files control and that the full-file/changes-only toggle remains available. Reviewers can open a file from Project Diff, use Option+Enter to switch between Project Diff and Solo Diff, and verify search follows the focused side in split diff mode. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase Solo diff views now retain the full-file/changes-only toggle without showing the unrelated expand/collapse-all-files control. <details> <summary>Click to view showcase</summary> <img width="1120" height="724" alt="Screenshot 2026-07-31 at 6 44 50 PM" src="https://github.com/user-attachments/assets/58519dda-d77a-410e-bbe2-0aebfac93fbd" /> </details> --- Release Notes: - Fixed a redundant expand/collapse-all-files control appearing in solo diff views. |
||
|
|
d73ad3de55 |
gpui: Give divs (the option for) a better scrolling experience (#61797)
# Objective Closes #56127 Right now there is an issue where in certain contexts, specifically GPUI div elements, horizontal scrolling w/ a trackpad works very poorly, even when trying to scroll sideways, vertical scrolling will happen. This happens with both a trackpad and scrollwheel. The showcase video also shows the broken behavior. ## Solution The way that scrolling works in the editor is really nice, scrolls are locked to the axis they started on but with enough force can change axis. so by taking the ongoing scroll handler from the editor and moving it up into GPUI, we can get that same functionality for GPUI. I somewhat "take over" the functionality of the existing `restrict_scroll_to_axis` property, because it seems like its purpose was basically trying to fix this problem already, just unsuccessfully. The alternative, and would make things overall nicer to look at, would be to tie this to `allow_concurrent_scroll`, but the effect radius tied to that option is way bigger, so im holding off on that atleast right now. ## Testing Theres a good number of scroll related tests generally, so I don't think i've perturbed any common existing behaviors. attach the functionality to `restrict_scroll_to_axis` really limits the surface. There are also some new tests for the ongoing_scroll behaviors. Tested on my mac w/ both trackpad and mouse. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase Video show casing all the behaviors: broken w/ trackpad working w/ trackpad broken w/ scroll working w/ scroll https://github.com/user-attachments/assets/1935cd2d-a255-4a77-81d5-daa9f72470a6 --- Release Notes: - markdown_preview: Fix horizontal scrolling inside certain elements |
||
|
|
b4f0eaf03f |
theme: Specify color format and pattern in schema (#49136)
## Purpose
While developing a theme for Zed I remarked that the schema available
doesn't mark colors in a way that Zed recognize to display the color
annotations:
```json
{
"$schema": "https://zed.dev/schema/themes/v0.2.0.json"
}
```
<img width="119" height="190" alt="Screenshot 2026-02-25 at 23 15 10"
src="https://github.com/user-attachments/assets/3f1bb703-cb26-4630-9598-3a7cb8873c20"
/>
But Zed has support for it when colors are marked with `"format":
"color"` in the schema:
<img width="127" height="186" alt="Screenshot 2026-02-25 at 23 14 58"
src="https://github.com/user-attachments/assets/1a9387a4-613a-4cf8-a3af-f6ac201bdf54"
/>
So I searched if the schema file was Open Source somewhere, discovered
it was generated from the codebase and attempted the change.
## Implementation
This is essentially done using a `ThemeColor` wrapper for the color
strings that implements `JsonSchema` with a dedicated regex for
validation and the color format specified. This ends up with a new
`$defs` of `Color` being specified and used:
```json
{
"$defs": {
"Color": {
"type": "string",
"format": "color",
"pattern": "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$"
}
}
}
```
## Other
- There is a small change I made for testing to the schema_generator
that adds an `--output` / `-o` flag. When provided it writes the
generated schema JSON to the specified file path instead of printing to
stdout. This was done to made testing easier but I can remove it or
split it to a separate PR (It's already a separate commit)
- For this PR to do anything a new schema version will need to be
published at something like `https://zed.dev/schema/themes/v0.3.0.json`
and documentation needs to be updated to point to it.
Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing (Manual testing, couldn't find any existing good place to test
it)
- [x] Done a self-review taking into account security and performance
aspects
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
|
||
|
|
777b94dfb4 |
search: Preserve cleared query when reopening the text finder (#61585)
## Context Closes #61394 The Text Finder persists the last query per workspace (in the `text_finder_queries` table) so it can seed itself on reopen. Persistence happens in `TextFinder::on_before_dismiss`, but it was guarded by `if !query.is_empty()`, so clearing the query and dismissing never wrote anything. The stale non-empty query stayed in the database and got restored on the next open, making it impossible to "clear and keep it cleared." This removes the guard so dismissal always persists the current query, including an empty one. The read side already treats an empty stored query as "nothing to restore" (`load_last_search` returns `None` for an empty string), so an empty write cleanly clears the seed instead of leaving the previous query behind. Manual test below : [Screencast from 2026-07-24 15-24-33.webm](https://github.com/user-attachments/assets/ba305f54-8ec2-4d3d-be0b-e2eb001bb204) ## How to Review **`crates/search/src/text_finder.rs`** `on_before_dismiss` no longer gates the write on a non-empty query. It always calls `store_last_search` with the picker's current query and options. `store_last_search` still early-returns for workspaces without a `database_id`, so unpersisted workspaces are unaffected, and `load_last_search` still maps an empty persisted query to `None`, so `seed_query` won't resurrect it. The active-item selection still takes priority over the persisted value on reopen, so seeding from a live editor selection is unchanged. The tests' shared `init_test` now installs a test `db::AppDatabase` global. This is required because the new test is the first one to actually reach `TextFinderDb::global(cx)`. The existing `test_dismiss_from_within_workspace_update` leaves the workspace's `database_id` as `None`, so it short-circuits before touching the DB. `test_clearing_query_does_not_restore_previous_query` exercises the real persistence path: it assigns a workspace `database_id` (`set_random_database_id` + `flush_serialization`), opens the finder with a query, dismisses, and asserts the query round-trips through `seed_query`; then it reopens, clears the query via `set_query("")`, dismisses, and asserts `seed_query` is now `None`. The positive round-trip assertion keeps the negative case from passing vacuously. ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed the project search / Text Finder restoring a previous query after it had been cleared and dismissed |
||
|
|
3d7c8e732e |
search: Escape seeded buffer search query in regex mode (#57748)
## What When `seed_search_query_from_cursor` is enabled and regex mode is active, the selected text is used verbatim as the regex pattern. This means selecting text like `z.d` seeds the regex `z.d`, where `.` acts as a wildcard — matching `zed`, `zXd`, etc. — rather than only the literal string the user selected. Fixes #57253. ## Why it was broken `search_suggested()` in `BufferSearchBar` retrieves the raw selection text from `query_suggestion()` and passes it directly to `search()`. There was no escaping step, even when `default_options` had `SearchOptions::REGEX` set. ## Fix Run the seeded suggestion through `regex::escape()` before passing it to `search()` when regex mode is enabled. This mirrors the identical pattern already used in `crates/vim/src/normal/search.rs:485`. ```rust // Before let search = self .query_suggestion(seed_query_override, window, cx) .map(|suggestion| { self.search(&suggestion, Some(self.default_options), true, window, cx) }); // After let search = self .query_suggestion(seed_query_override, window, cx) .map(|suggestion| { let suggestion = if self.default_options.contains(SearchOptions::REGEX) { regex::escape(&suggestion) } else { suggestion }; self.search(&suggestion, Some(self.default_options), true, window, cx) }); ``` ## Test Added `test_seeded_query_is_escaped_in_regex_mode` in `buffer_search.rs`. It creates a buffer with `"z.d\nzed\n"`, enables regex mode, selects `z.d`, seeds the search, and asserts: - The query text becomes `z\.d` (escaped), not `z.d` - Exactly 1 match is highlighted (the literal `z.d`), not 2 The `regex` crate was already a workspace dependency and is already used in the `search` crate transitively; this adds it explicitly to `crates/search/Cargo.toml`. Release Notes: - Fixed regex search seeded from cursor/selection matching more than the selected text when the selection contained regex special characters (e.g. `.`, `*`, `(`) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
c0af112ad5 |
search: Fix expand/collapse button for non multibuffer items (#61519)
# Objective Fix an issue where the button was being shown in the LSP log view even because it's `Item::buffer_kind` implementation was returning the default `ItemBufferKind::None` value. ## Solution Update the `BufferSearchBar::needs_expand_collapse_option` implementation to return `false` for all non-multibuffer items instead of only returning false for singletons. ## Testing Tested both manually as well as added a new test for this change – `search::buffer_search::tests::test_no_expand_collapse_option_when_item_is_not_buffer_backed`. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [ ] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [ ] Performance impact has been considered and is acceptable ## Showcase <details> <summary>Before</summary> <img width="3824" height="2482" alt="CleanShot 2026-07-23 at 11 18 37@2x" src="https://github.com/user-attachments/assets/f435ca07-5eb0-4c16-b567-ea066dbc0ccd" /> </details> <details> <summary>After</summary> <img width="3776" height="2482" alt="CleanShot 2026-07-23 at 11 19 53@2x" src="https://github.com/user-attachments/assets/b94e59cf-8888-470f-acd1-3bb1b714e62d" /> </details> --- Release Notes: - Fixed issue where "Collapse All Files"/"Expand All Files" button was being shown in LSP Log View |
||
|
|
756e764b90 |
project: Track inlay hint / code lens / document symbol registrations by ID (#55340)
extends the precedent set by #43703 (thanks @reflectronic) so that `textDocument/inlayHint`, `textDocument/codeLens`, and `textDocument/documentSymbol` correctly track multiple dynamic registrations by id. previously each register call overwrote the slot on `ServerCapabilities`, and unregister either silently did nothing (inlayHint, documentSymbol — no match arm) or wiped the entire capability (codeLens). now each method keeps its own id-keyed map on `DynamicRegistrations`; the field on `ServerCapabilities` is cleared only when the last registration is removed. textDocument-sync notifications (`didChange`/`didSave`/`willSave`) are deliberately out of scope — their fan-out semantics are ambiguous in the spec and were flagged on @smitbarmase's earlier exploration in #36876. verified with `cargo check -p project -p lsp -p editor`, `cargo test -p project --test integration -- multi_registration` (3/3 passing), and `cargo fmt -p project`. closes part of #37838. Release Notes: - Improved support for language servers that dynamically register inlay hints, code lens, or document symbols multiple times. --------- Co-authored-by: Kirill Bulatov <kirill@zed.dev> |
||
|
|
b832d440a2 |
search: Escape seeded project search query in regex mode (#61335)
Fixes what https://github.com/zed-industries/zed/pull/57748 does for buffer search. When project search is deployed with regex mode enabled and the query is seeded from the editor's selection or the word under the cursor, that text is literal, so regex chars in it (e.g. `.` in `z.d`) are now escaped instead of being interpreted as regex syntax. This follows how VSCode handles it. Release Notes: - Fixed project search queries seeded from the current selection being interpreted as a regular expression instead of literal text when regex mode was enabled. |
||
|
|
0d67b1a7ff |
search: Fix toggle soft wrap not working while the search bar is focused (#61150)
Closes #34698 The buffer search query input is itself an editor, so dispatching `editor::ToggleSoftWrap` from the command palette while the search bar had focus toggled soft wrap on the single-line query editor (with no visible effect) and never reached the searched editor. This intercepts the action on the search bar in the capture phase and applies it to the active searchable item, the same way `ToggleFoldAll` is already relayed. Focus stays in the search bar, so you can keep typing your query. `Editor::toggle_soft_wrap` and `Editor::soft_wrap_mode` become `pub` (matching `fold_all`/`has_any_buffer_folded`, which the existing `ToggleFoldAll` relay already uses). Includes a regression test that fails without the fix: it deploys the search bar, dispatches `ToggleSoftWrap` with the query editor focused, and asserts the searched editor's wrap mode changes while focus remains in the search bar. Release Notes: - Fixed `editor: toggle soft wrap` doing nothing when invoked while the buffer search bar was focused --------- Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com> |
||
|
|
d46e72221f |
text_finder: Seed query from focused item selection, including terminal (#60351)
## Summary Seed the text_finder's query from the focused pane's item instead of only the active center editor. Selecting text in the terminal or markdown_preview and opening text_finder now seeds that selection; the item next to focus wins when both it and a center editor have selections. If the focused item has no selection, the center item is tried, then the last persisted search as before. ## Test plan - Select a word in the terminal, open Text Finder, confirm it's pre-filled and searching - With a selection in both terminal and editor, confirm the focused one wins - Focus the terminal without a selection, confirm an editor selection still seeds - No selection anywhere, confirm the last search is restored - Confirm a selection in a markdown preview seeds too Release Notes: - Improved the Text Finder to seed its query from the focused item's selection, including the terminal --------- Co-authored-by: ozacod <ozacod@users.noreply.github.com> |
||
|
|
7113882745 |
git_ui: Restore search in solo diff views (#60936)
## Context Buffer search did not work in file diffs opened from the Git panel because `SoloDiffView` did not expose its embedded editor as searchable. Restoring search also revealed that the primary toolbar clipped several search controls, so the deployed search bar now uses the full-width secondary row for this view. Closes #60659. ## How to Review Three files changed. Read in this order: **`crates/git_ui/src/solo_diff_view.rs`** : `SoloDiffView::as_searchable` now returns its embedded `SplittableEditor`, restoring search for the focused diff side while keeping the editor hidden from global diff-style controls. **`crates/search/src/buffer_search.rs`** : Buffer search now detects when its searchable split editor is intentionally hidden by the containing item. When deployed, this case uses the secondary toolbar row so Toggle Replace, search options, match navigation, and match counts remain visible. Other multibuffer layouts keep their existing primary toolbar location. **`crates/git_ui/src/git_panel.rs`** : The regression test now opens a solo diff through the Git panel, confirms the split editor is searchable, deploys buffer search, verifies the secondary toolbar location, runs a query, and checks that the focused editor receives a search highlight. Manual test after the fix below : [Screencast from 2026-07-14 00-39-04.webm](https://github.com/user-attachments/assets/022ab106-d35a-4a75-98db-8809b86fa58d) ## Self-Review Checklist - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the UI/UX checklist - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Fixed searching in file diffs opened from the Git panel. Co-authored-by: Chris Biscardi <chris@christopherbiscardi.com> |
||
|
|
6bb578a5f1 |
Fix focus handling in ProjectSearchBar. (#61093)
# Objective Fix #61023 When project search is already open and focused, pressing the project search shortcut again (`cmd-shift-f` / `ctrl-shift-f`) only re-focused the query editor and did not select the existing query text. That made it hard to quickly retype a search term—especially after a no-results search, when focus stays in the search bar. This aligns project search behavior with buffer search, where `FocusSearch` focuses and selects the query. ## Solution In `ProjectSearchBar::focus_search`, call `focus_query_editor` instead of only focusing the query editor. `focus_query_editor` already focuses the field and selects all text (same path used by `DeploySearch`). ## Testing - [ ] Manual: open project search → type a non-matching query → Enter → press project search shortcut again → query text should be selected so typing replaces it - [ ] Manual: same flow after a search that returns matches - [ ] Manual: compare with buffer search (`cmd-f` / `ctrl-f`) to confirm consistent “refocus selects query” behavior - Platforms: tested / to be tested on macOS; Linux/Windows should behave the same via the shared `FocusSearch` action No automated test added yet; a `gpui::test` that deploys project search, dispatches `FocusSearch`, and asserts the query editor selection would be a good follow-up. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - N/A |
||
|
|
ae6cb0aff1 |
picker: Improve multi-select discoverability and rendering (#60919)
This PR reworks how multi-select mode is rendered in pickers (only used by the file finder and text finder). The "Multi Select" entry previously lived inside the footer's Actions menu, which was hard to discover and its toggle checkmark misaligned the menu's keybinding column. This PR changes to an icon button at the far-roght edge of the search editor, with a tooltip showing the keybinding to toggle it. Also made each list item use the actual Checkbox component instead of a bespoke re-implementation of it. And in doing so, added a few design improvements to the list item so that it received the checkbox while preserving proper styles for each interaction state, as well as displaying the keybinding to select the item or check the item. Here's a quick video, showing these changes off: https://github.com/user-attachments/assets/e142f7d1-87ba-4258-844b-953ed06237bd Release Notes: - Improved multi-select in the file finder and text finder: the toggle now lives in the search bar with a `cmd-shift-s` keybinding, and selection checkboxes render inside list items. |
||
|
|
ab43548338 |
a11y: Landmarks and menu improvements (#60397)
Fixes menu a11y, and adds landmarks with `F6`-navigation. Also fixes a GPUI bug, and adds debug actions for dumping a11y tree info. Since `F6` was already in use by the pause debugger keybind, also tightens up the debugger keybind context so they require an active debugger session. When there is one active, `F6` stays as pause debugger. `ctrl-F6` always works to go to the next landmark. Also adds an "accessible mode" setting. Currently, this only controls whether we show all menus all the time, but I suspect it will expand significantly in the future. Also adds `.aria_keyshortcuts()` API, but it's not wired up within accesskit adapters, so is not yet reported to screen readers. --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
304f264e76 |
pickers: Add multi-select support (#59931)
Users can now Cmd+click multiple files in the file picker and press Enter to open them all at once. Tab can also be used to select items without clicking, advancing the cursor automatically. # Objective Currently, when opening the file picker (Cmd+P), users can only open one file at a time. This adds multi-select support so users can select multiple files and open them all at once. Fixes #59818 ## Solution Added a `selected_indices` set to `Picker` to track which items the user has toggled into a multi-selection. Regular clicks still open a file immediately (unchanged behavior). Cmd+clicking adds a file to the selection without opening it, and pressing Enter opens all selected files at once. A `confirm_multi` method was added to the delegate trait so individual delegates (like the file finder) can handle opening multiple files with a safe fallback for delegates that don't support it. Multi-selection is cleared when the picker is dismissed or the search query changes. Selected items show a background highlight and a focused left border so the user always knows what's selected. ## How to use it 1. Open the file or test picker. 2. Search and either Cmd+click or tab it to add it to the selection (the file will not open yet). 3. Repeat for any other files you want to open. 4. To deselect a file, Cmd+click it again. 5. Alternatively, hover over an item and press Tab to select it with the keyboard, the cursor automatically moves to the next item so you can keep selecting quickly. 6. Once you have all the files you want, press Enter to open them all at once. ## Testing Tested manually on macOS. - **Single select:** Clicking on a file opens it directly, which is the existing behavior and remains unchanged. - **Multi-select via Cmd+Click:** Holding Cmd and clicking multiple items adds them to the selection. Cmd+clicking an already-selected item deselects it. Pressing Enter opens all selected files at once. - **Multi-select via Tab:** Hovering over an item and pressing Tab selects it without clicking or opening it, allowing keyboard-driven multi-selection. ## Showcase **Single select:** <img width="1512" height="982" alt="Screenshot 2026-06-25 at 6 45 33 PM" src="https://github.com/user-attachments/assets/8f9d4408-0688-4619-807a-affd6dc66f21" /> Opened single file <img width="1512" height="982" alt="Screenshot 2026-06-25 at 6 45 38 PM" src="https://github.com/user-attachments/assets/34ffacfd-b8ed-4898-beaa-bd5e47ebf682" /> - **Multi-select:** - Selecting multiple files <img width="1512" height="982" alt="Screenshot 2026-06-25 at 6 49 22 PM" src="https://github.com/user-attachments/assets/a7562fe8-9bd2-40ba-8bb4-12909ccefed7" /> Opened multiple files <img width="1512" height="982" alt="Screenshot 2026-06-25 at 6 49 42 PM" src="https://github.com/user-attachments/assets/c0c9e24c-86b7-45bf-898d-05068d5d7e3a" /> ## Release Notes: - Added multi-select to the file and text picker: Cmd+click or tab to select multiple files, then open them all at once. --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Yara <git@yara.blue> |
||
|
|
bfc278bee0 |
search: Fix ignored file search in nested Git directories (#60772)
# Objective - Fix ignored file search in nested Git directories (even just empty `.git` directories, not real git repositories) - Fixes #52328 ## Solution Keep parent ignore rules when rebuilding a nested repository's ignore stack. This hides root-ignored files again after excluded-file search is turned off, without breaking global ignore handling. For example: ```ascii project/ ├── .git/ ├── .gitignore # log/ ├── app/ │ └── a.txt # hello └── log/ ├── .git/ # nested repository marker └── b.txt # hello ``` Both `a.txt` and `b.txt` have string `hello`. Initially, searching for `hello` returns only `a.txt`. Enabling `Also search files ignored by configuration` rescans `log/` and returns both files. Before this change, disabling the option still returned both files because the rescan dropped the parent `.gitignore` and marked `b.txt` as included. ## Testing - Did you test these changes? If so, how? To test changes in this pull request create a simple project with the following dir structure: ``` .git .gitignore a/a.txt b/b.txt b/.git # this is an empty directory ``` Add `b` folder as an ignore entry to the `.gitignore` file: `b/` - Are there any parts that need more testing? No - How can other people (reviewers) test your changes? Is there anything specific they need to know? Use the test scenario above - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? macOS ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase By using the structure above here is how it works before changes here: https://github.com/user-attachments/assets/2028123e-388e-4390-b131-ddf4642ab5f3 Notice that `hello` string from file `b.txt` is listed in search results regardless of the option `Include excluded files` And here is after: https://github.com/user-attachments/assets/99c627a2-e16a-4fdd-979b-2e0bacbd827d Notice that `hello` string from file `b.txt` is **not** listed in search results when the option `Include excluded files` is disabled. Release Notes: - Fixed ignored file search in nested Git directories |
||
|
|
48192372a0 |
Git partially staged changes (#46541)
This PR explores the addition of a new feature and UI to improve visibility into partially staged commits. Currently, the Git panel shows tracked and untracked changes, but it does not clearly distinguish between staged and unstaged changes. As a result, it’s difficult to quickly see which changes are not staged in the current UI. Both staged and unstaged changes are combined into the `Uncommitted Changes` multibuffer. This developer experience differs from other editors, most notably VS Code; which presents separate Staged Changes and Changes lists. ### Staged and unstaged diffs in multibuffers This PR introduces an alternative UI for unstaged changes that aligns with the overall Zed experience. Instead of showing changes on a per-file basis, staged and unstaged diffs are each displayed in their own multibuffers, similar to how `Uncommitted Changes` currently works. For example the following screenshot shows the current `Uncommitted Changes` on the left, the `Staged Changes` in the middle and the `Unstaged Changes` buffer on the right for comparison <img width="1408" height="859" src="https://github.com/user-attachments/assets/aa709f7a-041d-4cb1-95d6-84c0f5fff688" /> ### Indicators/interactions The new multibuffers can be opened in two ways: 1. Via a new `U` chip, which appears when a file has unstaged changes 2. Via new menu options (See screenshots below for both interaction paths.) <table> <tr> <td style="text-align: center; vertical-align: top;"> <p>via the chip</p> <img height="400" src="https://github.com/user-attachments/assets/3ef69f02-b787-499c-959a-25f50b3728e8" alt="Via the chip" /> </td> <td style="text-align: center; vertical-align: top;"> <p>via the menu</p> <img height="400" src="https://github.com/user-attachments/assets/f5be8b6d-ccdc-4420-bd29-75570b558016" alt="Via the menu" /> </td> </tr> </table> ### Design goals - minimally intrusive UI changes (small new badge and menu items) - adhere by Zed'ism (use multibuffer where possible) - avoid disabling any current interactions (Uncommitted Changes ui is unchanged) - avoid introducing an app level view mode (no new settings needed) ### Experience goals - make it easy to see what changes are not staged - make it easy to see that a file has unstaged changes (avoid developers accidently leaving out changes in a commit; a personal issue that I have when using Zed) - elegantly handle large file's unstaged changes (follows the same collapse and expanding seen in `Uncommitted Changes`) ### How to try - Clone the repo and run `cargo run` - Make a change to a file and stage it - Make another change to the file (the `U` indicator will appear) - Click the `U` to see the unstaged view ### Open questions/rough edges - [ ] determine if this user experience is useful for others - [ ] ensure all interactions work as expected (response to all update cases) In general I'm really interested in hearing the community's feedback about this interface, more than happy to make any changes or explore a different solution! ### Related issue: - https://github.com/zed-industries/zed/pull/36646 - https://github.com/zed-industries/zed/issues/26560 Release Notes: - Support partially staged commit multibuffers via a staged and unstaged changes view. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Cole Miller <cole@zed.dev> |
||
|
|
e41a55c3c0 |
Improve diff tabs toolbar design (#60464)
This PR adds a bunch of design improvements to the toolbar of (tab) views that display diffs: the uncommitted changes, branch diff, and agent diff tabs. This involves adjusting spacing, sizing, and other small tweaks across all of these views, including touching up the divider component API a little bit, adjusting Git icons design, adding diff stat numbers to the uncommitted changes tab so its consistent with the others, and more (e.g., moving the split buttons into its own component to ensure they look the same across all uses). Ended up also going on a slight de-tour to make all uses of the split button in the Git panel consistent design-wise. All in all, this is just tidying up the design of all of these surfaces that are all relatively similar. | Branch Diff | Uncommitted Diff | Single-file Diff | Git Panel | |--------|--------|--------|--------| | <img width="800" alt="Screenshot 2026-07-06 at 11 25@2x" src="https://github.com/user-attachments/assets/4ebf87e7-c52d-41d9-9de3-7944125114a1" /> | <img width="800" alt="Screenshot 2026-07-06 at 11 25 2@2x" src="https://github.com/user-attachments/assets/51ccd2eb-904b-455a-a708-b4cb50b3a7cb" /> | <img width="800" alt="Screenshot 2026-07-06 at 11 26@2x" src="https://github.com/user-attachments/assets/6ae7df68-d1bd-4d36-a250-ba16e43c4e8e" /> | <img width="800" alt="Screenshot 2026-07-06 at 11 26 2@2x" src="https://github.com/user-attachments/assets/e032bc60-4551-41f0-b578-90ed305167c2" /> | Release Notes: - Added diff stat numbers to the uncommitted changes view. |
||
|
|
1aa80354a4 |
Fix text finder crash from unbounded memory use (#60377)
- Fixes #60238. - The text finder could spike memory into the tens of gigabytes and crash the app. The finder was copying the full matched line into every match it kept, so memory grew with the number of matches times the size of each line. Enough matches carrying enough text and the process runs out of memory. ## Solution - Stop storing line text on matches. Each match now keeps only its position and column, and the text shown in a row is built lazily for the visible rows, using a bounded slice around the match rather than the whole line. Line boundaries come from the buffer's line index instead of re-scanning the content per match. - Cap the number of matches the finder builds while streaming results, using the same ceiling project search already applies. This keeps the finder from ever assembling an unbounded match list on the UI thread. - Behavior is unchanged: every occurrence is still its own row, jumping to a match lands on the exact line and column, and the rendered text and highlighting look the same. The finder just no longer holds text proportional to the match count. ## Testing - Added tests covering the new behavior: the match count is capped while streaming, every occurrence below the ceiling still becomes its own match at the correct line and column, and the rendered slice around a match stays bounded on a huge line while still covering a whole short line. - Verified by hand with the reproduction from the issue. The screenshot below shows the memory usage and the matching against the issue data: <img width="1277" height="1053" alt="Screenshot 2026-07-03 at 17 43 11" src="https://github.com/user-attachments/assets/71c0aa3b-2423-427d-91ba-792951d9ba31" /> ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed a crash and high memory usage in the text finder. |
||
|
|
82fb058ed0 |
text_finder: Fix crash when dismissing the finder (#60437)
# Objective Fixes #60436 Pressing Escape (or triggering any workspace-level action that closes modals, such as `pane::DeploySearch` / `search::NewSearch`) while the Text Finder was open crashes the app with: ``` cannot read workspace::Workspace while it is already being updated crates/gpui/src/app/entity_map.rs:164 ``` `TextFinder::on_before_dismiss` read the `Workspace` entity (`workspace.read(cx).database_id()`) to persist the last search query. Dismissal can be initiated from inside a `workspace.register_action` handler — e.g. `buffer_search`'s `SearchActionsRegistrar` calls `workspace.hide_modal(...)` while the `Workspace` entity is leased — so the modal layer invokes `on_before_dismiss` synchronously under that lease, and the read trips GPUI's re-entrancy guard. Since the finder seeds the last query on open, the query is non-empty immediately, making the crash reproducible on the very first Escape. Dump file analysis confirms the diagnosis. ## Solution Stop reading the `Workspace` entity in the dismiss path. Both places that create the modal (`TextFinder::open` and `TextFinder::open_from_project_search`) already run inside `workspace.update_in`, where `workspace.database_id()` is a plain field access on `&mut Workspace`. Capture the `Option<WorkspaceId>` there, store it on `TextFinder`, and have `on_before_dismiss` use the stored id. The dismiss path now touches no entity that can be mid-update, so it is safe regardless of which code path initiates `hide_modal`. The remaining reads in `on_before_dismiss` (`picker` and its query editor) are never leased in any dismissal chain. The `id` is captured once at creation; a workspace that gains a database id during the modal's lifetime would persist under `None` (i.e. skip persistence), which matches the previous behavior for unpersisted workspaces. ## Testing - Verified the fix by code review and re-tested in a rebuilt bundle (local build). - To reproduce/verify: open the Text Finder (`text_finder::Toggle`), type a query (or rely on a seeded one), then press Escape with a binding that resolves to `editor::Cancel`, or press `cmd-shift-f` (`DeploySearch`) while the finder is open. Before this change the app crashes. After it, the modal dismisses and the query is persisted. - Tested on macOS 26.5.1 (arm64); the affected code is platform-independent. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks — no unsafe blocks - [x] The content adheres to Zed's UI standards — no UI changes - [x] Tests cover the new/changed behavior — added - [x] Performance impact has been considered and is acceptable — one `Option<WorkspaceId>` copy at modal creation --- Release Notes: - Fixed a crash when closing the Text Finder while a workspace action (e.g. Escape via `editor::Cancel`, or deploying search) triggered the dismissal |
||
|
|
a378682f2f |
text_finder: Add collapsible file groups (#60193)
## Summary Add a chevron (`Disclosure`) to each file group header in Text Finder, letting you fold/unfold that file's matches. Fold state is cleared whenever a new search starts. ## Test plan - [x] Open Text Finder, run a search with matches in multiple files - [x] Click a header's chevron, confirm its matches hide/show and selection lands on a visible row - [x] Start a new search, confirm folded state doesn't carry over Release Notes: - Added the ability to collapse per-file match groups in Text Finder --------- Co-authored-by: ozacod <ozacod@users.noreply.github.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
ba82a7358b |
text_finder: Seed last query and filters to make quick edits easier (#59849)
## 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. --------- Co-authored-by: ozacod <ozacod@users.noreply.github.com> Co-authored-by: Yara 🏳️⚧️ <git@yara.blue> |
||
|
|
df83598915 |
Improve overall compilation stats after the telescope picker feature (#60114)
Follow-up to https://github.com/zed-industries/zed/pull/59604
Build stats changes for `cargo clean && RUSTC_WRAPPER=
CARGO_BUILD_RUSTC_WRAPPER= cargo build --timings -p zed`:
```
===== BASE (
|
||
|
|
c8522e6d52 |
text_finder: Open match on the right column (#59840)
## Summary When opening a result from the text finder navigate to the exact match position the same way project search already does. Previously the text finder opened the file at the start of the matched line, while project search lands the cursor on the start of the match (correct line and column). ## Solution `go_to_singleton_buffer_point` now uses `SearchMatch::relative_range.start `as the column instead of 0. ## Testing - Manual: search in the text finder → open a result whose match starts mid-line → cursor lands on the start of the match. Verified for both opening in the current pane and opening in a split. Release Notes: - Improved text finder to open files at the matched column Co-authored-by: ozacod <ozacod@users.noreply.github.com> |
||
|
|
e07635b0c0 |
text_finder: Seed text finder query from active project and buffer search (#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> |
||
|
|
5bf85b2149 |
text_finder: Send selected word to text finder query (#59766)
## Objective Make text finder match project search and buffer search by pre-populating its query from the active editor according to `seed_search_query_from_cursor`. ## Solution - Seed text finder from the active editor's query suggestion when opening it. - Pass the seeded query into the picker and select the query text so typing replaces it immediately. ## Testing - Manually tested visually by opening text finder from an editor with a selection and with the cursor on text, confirming the query is pre-populated and selected. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Improved text finder to seed its query from the active editor. Co-authored-by: ozacod <ozacod@users.noreply.github.com> Co-authored-by: Yara 🏳️⚧️ <git@yara.blue> |
||
|
|
be50aaccbe |
picker: Simplify presentation and sizing APIs, add preview-aware defaults (#59719)
The recent "pickers with previews" overhaul left the picker
sizing/presentation API spread across several overlapping knobs that
every call site had to set correctly — and many didn't, causing pickers
across the app to render at the wrong width, lose their container, or
stop dismissing. This PR consolidates that surface into a small,
hard-to-misuse API and makes correct sizing the default.
Net effect: a plain `Picker::uniform_list(delegate, …)` now renders
correctly out of the box (standard width, standard max-height, shrinks
to fit, dismisses properly), and the ~35 call sites only specify what
genuinely differs.
## API changes
**Presentation** — three overlapping booleans (`is_modal`, `is_popover`,
`is_resizable`) collapsed into one enum, with resizability living inside
the only variant where it's meaningful:
```rust
enum Presentation {
Modal { resizable: bool }, // own chrome, dismisses on blur, optionally resizable
Popover, // own chrome, dismisses on blur, never resizable
Embedded, // host container owns chrome + dismissal
}
```
- `modal(bool)` is **removed** in favor of explicit, self-documenting
builders:
- *(default)* → `Modal` (resizable iff it has a preview)
- `.popover()` → `Popover` (menu-attached surfaces)
- `.embedded()` → `Embedded` (pickers nested in a larger modal/view)
- Dynamic callers use `.when(cond, Picker::embedded)` (added `impl
FluentBuilder for Picker`).
**Sizing** — preview-vs-not now drives everything; the manual padding
knob is gone:
| Before | After |
|---|---|
| `vertical_padding` field + `no_vertical_padding()` | removed — derived
from whether a preview is visible |
| `height(...)` (ambiguous: fixed vs max) | `max_height(...)` (plain
pickers shrink-to-fit, capped here) |
| `minimum_results_width(...)` | removed — a plain picker's min width
tracks its opening width; preview pickers use standard internal pane
mins |
| default size = 60% viewport | default = `DEFAULT_MODAL_WIDTH` (34rem)
× `DEFAULT_MODAL_MAX_HEIGHT` (24rem, max) |
| resize handles gated on `is_modal` | gated on `is_resizable` (new
`resizable(bool)` builder; auto-`true` for preview pickers) |
Call sites now only override the exceptions: narrow popover selectors
(`initial_width`), the taller outline view (`max_height`), and preview
pickers (constructed via `*_with_preview`).
## Behavior fixes
- **Wrong widths everywhere**: pickers were falling back to
60%-of-viewport because the original migration set
`minimum_results_width` but never `initial_width`. Fixed at the source
via the new defaults.
- **Popovers had no container and wouldn't dismiss**: `is_modal=false`
was suppressing both the elevated background *and* blur-dismiss. Split
out so popovers keep their chrome and dismiss on click-away/escape. This
fixed the agent-panel model/profile selectors, sidebar recent projects,
and the settings theme/font/icon/ollama pickers (which were incorrectly
using `modal(false)`).
- **Sidebar recent projects stretched to full height**: was missing the
shrink-to-fit behavior; now capped and content-sized like other
popovers.
- **Preview crash**: removed an over-strict `debug_assert!` that
panicked when previewing an empty file (`message == None && editor
empty` is valid).
- **Preview-aware default size**: pickers open at standard width with
the preview hidden, and expand to the larger "telescope" size when a
preview is shown. Fixes the text finder rendering super-wide by default,
and makes the file finder expand (rather than cram its results) when you
toggle the preview.
---
Release Notes:
- N/A
|
||
|
|
c84982260e |
Migrate missed pickers to new width system (#59693)
# Objective - Fixes #59643. ## Problems - Initial and minimum width was not migrated for all pickers. - Some pickers had their width still determined by their wrapper. - Some pickers where not modals but did not have modal false set. ## Solution - Migrate the pickers we missed. - Remove the width being set on the div's wrapping the pickers. - Set modal false on the missed pickers. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - N/A |
||
|
|
6a6fcbebc4 |
Add preview to pickers and make them resizable (#59604)
Overhauls Zed's pickers to make them resizable and give them a preview. Closes #8279 ### Background The most requested Zed feature has the last year has been a [Telescope like search box](https://github.com/zed-industries/zed/issues/8279) [discussion](https://github.com/zed-industries/zed/discussions/22581). To understand why this is so popular we need to understand search can serve thee goals: - Navigation: fuzzy search is faster & easier then clicking in a file tree - Exploration: example, find a function by a word in its doc comment - Collecting: example, getting a list of functions to change The project search which shows results in a multibuffer is the perfect way to operate on a list of items. Navigation and Exploration need a lot of context around each result and offer fast navigation between them. For both of these live searching is also critical. The `telescope UI` is a picker with a preview to the right or below. It's offered in various editors and IDE's most famously Neovim (through the Telescope plugin), IntelliJ (natively), Helix (natively) and of course VScode (plugins) and it's _many_ forks. While having a UI like that for text search (our project search) is most requested the UX pattern is applied widely, from `find_all_references` to `bookmarks`. It enhances most pickers. Note that we have over 50 different picker modals! The community has tried to build something like this for Zed: - https://github.com/zed-industries/zed/pull/44530 - https://github.com/zed-industries/zed/pull/45307 - https://github.com/zed-industries/zed/pull/46478 - https://github.com/zed-industries/zed/pull/43790 These all became huge PR's that we could not merge for various reasons. This is a really hard feature to integrate in Zed! This PR got started as https://github.com/zed-industries/zed/pull/46478 and supercedes that. ### Design - Extend pickers to support an optional preview with minimal changes to the pickers themselves. - Make pickers resizable. - Complement the existing search do not replace it by having both UI's share the underlying search and allow freely switching between them. - Allow extending the preview to things other then files. - Maintain a clean design on all the pickers. ### Heigh level Implementation overview - Adds an `Option<Preview>` to `Picker` - Gives `PickerDelegate` a method to communicate a preview to the Picker - Overhaul the way pickers are drawn to allow for resizing them. Implemented on the `Shape` and `SizeBouds` structs. - Adds a high level way to draw the `footer` and `editor` so we do not need to change much to the pickers. - Adds a new text finder Picker - Adds a way to take a running search from project search and hand it to the text finder Picker and the other way round - Give the file finder a preview ### Next steps A more detailed list and how to help out will be added to the tracking issue for [Pickes with previews](https://github.com/zed-industries/zed/issues/56037) - Add more previews to more pickers! - Enable selectioning multiple items in pickers and performing actions on those - Open selected items in a multibuffer - Add a way to restore the last picker - Make popovers (picker attached to some menu) resizable as well ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase TODO (will be done post merge) --- Release Notes: - Added resizing via dragging to all picker modals. - Added a preview to the File finder, the preview can be to the right or below. - Added a Text finder picker with a preview as alternative project search UI. The search is shared and allowes switch between UIs while running. --------- Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com> Co-authored-by: ozacod <ozacod@users.noreply.github.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
69946b28da |
agent: Warn about long skill descriptions (#58356)
Closes #58046 Closes AI-353 Skills with descriptions over the 1024-byte limit now load with a warning instead of failing. The warning appears in the thread footer with clickable skill file rows, and the skill picker keeps the skill icon while showing a right-aligned warning badge whose hover text explains the issue. Warning for single out-of-spec skill <img width="2790" height="870" alt="image" src="https://github.com/user-attachments/assets/f454b55a-8e05-438e-b4ff-356259ff6843" /> Warning for multiple out-of-spec skills <img width="2796" height="646" alt="image" src="https://github.com/user-attachments/assets/a0808cdd-4857-4a6b-a26e-15156afbffe9" /> Skill selection popup <img width="1234" height="1118" alt="image" src="https://github.com/user-attachments/assets/5bb463f6-7adb-4e39-8522-e322bf078aff" /> Skill management in settings <img width="1768" height="1390" alt="image" src="https://github.com/user-attachments/assets/85c6b179-e268-4518-8ca7-c73b55f92355" /> Release Notes: - Allow loading skills whose descriptions exceed the 1024-byte limit by showing warnings instead of failing to load them. --------- Co-authored-by: Martin Ye <martin@zed.dev> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
d6d4fbbce0 |
project: Treat replacement literally when dealing non-ASCII text search (#56123)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #55503 In #28752, to support case-insensitive search for non-ASCII queries, Zed internally falls back to a regex search. However, this also affected the replacement behavior, as the replacement code implemented a simple match logic: https://github.com/zed-industries/zed/blob/ae6b48c423d3e429ffd242c2771d65ae450640af/crates/project/src/search.rs#L452-L457 Since the regex fallback is an internal implementation detail (the user never enabled regex mode), the replacement should behave the same as a normal text replacement. This PR fixes that. Release Notes: - Fixed replacement text being treated as a regex pattern when performing case-insensitive text search with non-ASCII characters. |
||
|
|
3d5f7d4762 |
gpui: Allow chaining flex_grow() and flex_shrink() with custom factors (#58142)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Release Notes: - Allow chaining of `flex_grow()` and `flex_shrink()` with custom factors, following Tailwind CSS conventions. _For example:_ <img width="509" height="308" alt="aaa" src="https://github.com/user-attachments/assets/02094fb2-d762-4ac9-a1d9-ef06e2fb047f" /> Before: ``` rust div() .flex() .flex_row() .size_full() .bg(gpui::white()) .child( div() .map(|mut this| { this.style().flex_grow = Some(1.); this }) .bg(gpui::blue()), ) .child( div() .map(|mut this| { this.style().flex_grow = Some(2.); this }) .bg(gpui::green()), ) .child( div() .map(|mut this| { this.style().flex_grow = Some(3.); this }) .bg(gpui::red()), ) ``` After: ``` rust div() .flex() .flex_row() .size_full() .bg(gpui::white()) .child(div().flex_grow(1.).bg(gpui::blue())) .child(div().flex_grow(2.).bg(gpui::green())) .child(div().flex_grow(3.).bg(gpui::red())) ``` |
||
|
|
4bc769a328 |
Make project panel to auto reveal multi buffer excerpts with latest selection (#57236)
Make non-singleton editors to return project paths by adding a `fn active_project_path`: this had been added as `fn project_path` and similar already, so the PR replaced those methods with the generic one now. Before: https://github.com/user-attachments/assets/d0773e18-3910-4c5b-bcb3-a742f9bf9691 After: https://github.com/user-attachments/assets/e7a3f13e-9649-4564-a7e6-dccf54f8c000 Release Notes: - Made project panel to auto reveal multi buffer excerpts with latest selection |
||
|
|
1af4a3a2e1 |
Fix macOS find query seeding (#56681)
Closes #55619 ### Summary - Route `buffer_search::UseSelectionForFind` through `BufferSearchBar::deploy` instead of updating the query editor directly. - Add an explicit seed-query override to `deploy`, so the Cmd-E action can force `SeedQuerySetting::Always` while regular deploy callers continue to pass `None` and respect the user’s `seed_search_query_from_cursor` setting. - By going through `deploy`, Cmd-E now also runs the search path that keeps buffer-search navigation state in sync: - shows/initializes the search bar for the active searchable item - applies the seeded query via `search_suggested` - calls `search`, which updates the query editor, search options, active search query, search history, and macOS find pasteboard - refreshes `searchable_items_with_matches` and `active_match_index` - activates the current match after the search completes - This ensures the subsequent Cmd-G action has the expected active query, match list, search token, and active match index to select the next result. - Add a macOS-only end-to-end regression test using the default macOS keymap with `simulate_keystrokes("cmd-e")` and `simulate_keystrokes("cmd-g")`. ### Validation - `cargo test -p search test_cmd_e_then_cmd_g_uses_selection_for_find` - `cargo fmt --check --package search --package zed_actions` - `./script/check-keymaps` - `cargo check -p search` - `cargo check -p workspace` - `cargo check -p vim` Release Notes: - Fixed macOS Cmd-E/Cmd-G find behavior so Cmd-E seeds find from the cursor or selection and Cmd-G advances through the newly seeded matches. |
||
|
|
4f73a61cab |
Make all status bar tools able to hide its button via UI (#54971)
Closes https://github.com/zed-industries/zed/discussions/53471 Adds a requirement on status bar items to provide a way to hide themselves. <img width="329" height="153" alt="image" src="https://github.com/user-attachments/assets/b98ee5ba-a439-44d7-9ab5-f4511b66a574" /> <img width="464" height="40" alt="image" src="https://github.com/user-attachments/assets/b41d9189-3475-4e61-b3a4-bc731dd52c53" /> Release Notes: - Added a way to hide sidebar buttons |
||
|
|
cb7a717a67 |
Merge gpui::Task and scheduler::Task (#53674)
Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
611dc0bcfd |
project_search: Fix project search status text and refactor search state (#54753)
This change fixes a small bug where we were showing "Loading project..." even when in fact we had already started the search. It also refactors three booleans in the `SearchState` enum, so that it's harder to make similar mistakes in the future. Release Notes: - N/A |
||
|
|
e1a69bdc8f |
Remove smol as a dependency from a bunch of crates (#53603)
We aren't making use of it in these crates and it unblocks some web-related work Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
c49ffd1e88 |
Fix bad GitHub merge queue merge (#54721)
No, sadly, the title is not a typo. See https://www.githubstatus.com/incidents/zsg1lk7w13cf for the context. I'll read with joy and popcorn through that root cause analysis. It makes literally zero sense what happened here, but for some completly bonkers reason GitHub completely messed up the merge queue with https://github.com/zed-industries/zed/pull/54632. I have no idea how it happened. It makes literally zero sense. A PR going into the merge queue should have the same LoC when getting out of it. GitHub obviously does not check this. GitHub causes extra work with a feature that is supposed to save time. Thanks, I guess. Release Notes: - N/A --------- Co-authored-by: Danilo Leal <daniloleal09@gmail.com> |
||
|
|
184e1d93e3 |
branch_picker: Add button to filter remote branches (#54632)
This PR brings back the button to filter remote branches when accessing the title bar's branch picker with the mouse. It was unintentionally removed when we introduced the new worktree picker. Release Notes: - N/A |
||
|
|
b34513a720 |
search: Fixed highlighting item beyond cursor (#54514)
Search is highly generic, editor is the only implementation that has a concept of a cursor. When the cursor moves eventually `Editor::selections_did_change` runs which among a bunch of things triggers the `SearchEvent::ActiveMatchChanged`. This was handled by the `BufferSearchBar` by moving the currently highlighted item. When going to the next search result (from the cursor position) we call `BufferSearchBar::match_index_for_direction`. It relied on the current_index being updated during the handling of `ActiveMatchChanged` which we removed. It now instead figures out the next/prev search result from the users cursor in the buffer directly. The `SearchEvent::ActiveMatchChanged` was being used for different responsibilities in different places in the codebase where it was emmited, namely: * On the `editor::Editor::selections_did_change` it was being emmited in case a single selection (single cursor) existed, and this was the thing reponsible for indirectly updating the active match as soon as the cursor moved out of match. * On the `terminal` side, it's being emitted when the user clicks on the terminal, to "simulate" what the cursor position would be and update the active match to the next closes match compared to the click position. * On the `markdown_preview` side it was being emmited whenever the active match was updated but, from testing, it does actually seem to not drive anything and is unnecessary? Given that we no longer want to update the active match in the buffer everytime the user moves the cursor, we removed the event emission from `editor::Editor::selections_did_change` as well as removing the one from `markdown_preview`, as it seems it doesn't have any noticeable impact. Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable Closes #44367 Release Notes: - Fixed search highlighting changing anytime the cursor moves. --------- Co-authored-by: Yara <git@yara.blue> |