0f7dc9a9edded91df1ca5cc2e6c8486a5d24bd71
38562
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
0f7dc9a9ed |
agent_ui: Use the thread title for agent notifications (#59377)
The agent-waiting notification heading was hardcoded to the agent id, showing "claude acp" for external agents. Use the thread's own title, which external agents now provide via session info updates, and fall back to the agent id only for threads that aren't titled yet. # Objective - External agent notifications were just headed generically I.e. "claude acp". There was a TODO in the code to use the thread name, so that it's clear which thread actually produced the notification. ## Solution - Use the thread name, seems it was inscope in the code already from a previous change. ## Testing Tested manually by triggering a notification and seeing the thread name instead of acp-claude. ## 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 - this code path wasn't tested and doesn't seem like it needs it, but willing to be corrected. - [x] Performance impact has been considered and is acceptable Release Notes: - agent: Include thread title in notification when Zed is not focused |
||
|
|
42df2ba903 |
vim: Fix cw with count greater than 1 not preserving whitespace correctly (#56585)
In vim, `c {count} w` diverges from the default `w` motion behavior: For
change operations, the `w` motion will be treated like the `e` motion if
the cursor is on a word, preserving whitespace after the N-th word. In
zed, this special case was only implemented for a count of 1, falling
back to incorrectly using the `w` motion if the count is greater than 1.
This PR generalizes this implementation to handle this special case for
any count.
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 #56563.
Release Notes:
- Fixed: vim `cw` with count greater than 1 not preserving whitespace
correctly
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
|
||
|
|
0e509c9b96 |
zed: Respect default_open_behavior when opening from Finder (#59551)
Closes #59540 Release Notes: - Respect `default_open_behavior` when opening Zed via File Explorer/Finder |
||
|
|
0cb01a60d6 |
Bump Zed to v1.9.0 (#59486)
Release Notes: - N/A Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
44487855ad |
editor: Add the git blame toggle to gutter context menu (#59460)
# Objective
- Add a quick way to toggle the **Column Git Blame** gutter directly
from the editor's gutter context menu, so users don't have to move the
cursor to the top-right corner or status bar to enable/disable blame
annotations.
## Solution
- Added a `toggleable_entry("Column Git Blame", ...)` item to the
existing gutter context menu in `crates/editor/src/editor.rs`.
- Selecting it calls `Editor::toggle_git_blame`, which flips
`show_git_blame_gutter` on or off, matching the behavior of the existing
toolbar/status-bar control.
- The entry appears as a toggleable item with the git blame icon,
reflects the current blame state, and reuses the existing
`toggle_git_blame` action/handler so behavior stays consistent with the
rest of the UI.
## Testing
- Added a unit test in `crates/editor/src/editor_tests.rs`
(`test_gutter_context_menu_git_blame_toggle`) that builds the gutter
context menu and verifies selecting the Column Git Blame entry toggles
`show_git_blame_gutter` on and then back off.
- Ran `cargo test -p editor --lib
test_gutter_context_menu_git_blame_toggle` — passes.
- Ran `./script/clippy -p editor` — clean.
- Are there any parts that need more testing? I think No — the change is
a straightforward menu hook into existing state.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know?
1. Right-click the gutter of any file in the editor.
2. Confirm **Column Git Blame** appears in the menu.
3. Click it — the blame gutter should appear.
4. Open the menu again and click it — the blame gutter should disappear.
- If relevant, what platforms did you test these changes on, and are
there any important ones you can't test? Tested via unit tests on macOS.
No platform-specific code was added.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — no unsafe blocks
- [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 — reuses
existing toggle handler, no extra work
## Showcase
> No visual redesign; just a new menu entry.
- Right-click the editor gutter to access the new **Column Git Blame**
toggle.
![Gutter context menu showing Column Git Blame option]
<img width="369" height="248" alt="image"
src="https://github.com/user-attachments/assets/7c83ad91-ae7e-4562-8faf-a17c8b92bdc1"
/>
and not toggled
<img width="409" height="389" alt="image"
src="https://github.com/user-attachments/assets/206a40c0-0933-4720-bc3e-5627786eae43"
/>
---
Release Notes:
- Added a git blame toggle to the gutter's context menu
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
|
||
|
|
7b8f639735 |
Make grep tool results clickable in agent panel (#59230)
The agent panel's `grep` tool output previously rendered file paths and line numbers as plain markdown text, so search results weren't clickable (unlike `find_path`, which emits `ResourceLink` content blocks). This PR makes `grep` results clickable in the same way `find_path` does: - `grep` now streams a `ResourceLink` content block per match (`crates/foo/bar.rs#L12-15` → `file:///abs/path#L12-15`) followed by the code snippet, via `event_stream.update_fields`, and sets `locations` on the tool call. - `render_resource_link` in `agent_ui` now splits an optional `#L...` fragment off `file://` URIs before resolving the project-relative path, so labels render as `path#L12-15` instead of falling back to the raw absolute URI. Clicking opens the file at the matched line (handled by the existing `MentionUri` selection parsing). - The model-facing text output of the tool is unchanged. Closes AI-401 Release Notes: - Improved the agent panel so that file search results from the agent's `grep` tool are clickable and open the file at the matched line. |
||
|
|
b5f16f69e8 |
agent_ui: Add in-thread search bar (#57231)
This is a narrower alternative to #54816, scoped to search only the currently-loaded thread, excluding tool output or thinking blocks (happy to follow up on those, see next). It uses a custom bar confined to `agent_ui` rather than `BufferSearchBar` + `SearchableItem`, avoiding the cross-crate plumbing that #54816 reached. Open as draft pending direction from @benbrandt on what scope/approach would be acceptable for in-thread search. <img width="959" height="609" alt="image" src="https://github.com/user-attachments/assets/8971e432-61d3-46db-a6a4-2bbd355089e7" /> ## What this PR does Adds a search bar to the agent panel, triggered by Ctrl+F (Cmd+F on macOS), that lets users grep the currently-loaded thread without leaving the agent panel; not cross-thread or cross-agent. - Searches visible content only: user messages, assistant message chunks, and tool-call labels. Thought blocks and rendered tool-call content (collapsed by default) are intentionally skipped so that: 1. The visible match count matches what the user sees. 2. The search experience is consistent between tool output blocks in the current Zed session, ans tool output blocks from past sessions, which are not rendered - see issue #57230 - Highlights matches inline via `Markdown::set_search_highlights` for markdown-rendered content and `Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)` for past user messages (rendered through `MessageEditor`'s inner `Editor`, not through markdown). - Next/prev navigation, case/whole-word/regex toggles (same UI as `BufferSearchBar`). - Returns focus to the message editor on dismiss so the user can keep typing immediately. <details><summary>Commits (authored by Claude 4.7 Opus, max)</summary> ### Seven logical commits 1. **`agent_ui: Add in-thread search bar`** — initial implementation: bar UI, keymap bindings under `AcpThreadSearchBar` context, markdown highlight plumbing, focus-restore on dismiss. 2. **`agent_ui: Add unit tests for in-thread search`** — coverage of the matcher across entry kinds and the dismiss-clears-highlights path. 3. **`agent_ui: Limit search to visible tool-call text`** — UX fixes from manual testing: `track_focus` so `AcpThreadSearchBar` context lands in the editor's dispatch chain; red border on zero-match query; skip tool-call content (only search labels). 4. **`agent_ui: Fix Esc dispatch, smart toggle, error message, skip Thought blocks`** — round 2 of UX fixes: contribute `AcpThreadSearchBar` context from `ThreadView` when bar is visible, smart Ctrl/Cmd+F outside-the-bar focuses instead of closing, regex error message row, skip `AssistantMessageChunk::Thought`. 5. **`agent_ui: Polish thread search bar — Esc routing, user-message highlights, action forwarding`** — `search::*` action forwarders on `ThreadView`; `cx.defer` around the activate callback (fixes a double-borrow panic); `editor::actions::Cancel` interception so Esc dismisses our bar instead of escaping to the workspace's `BufferSearchBar`; user-message highlights via the inner `Editor`; muted zero-match counter; three new gpui regression tests. 6. **agent_ui: Fix Shift+Enter shadowing in thread search bar`** — capture-phase intercept of `editor::Newline*` on the bar's `bar_row` element so a base keymap binding `shift-enter` at the `Editor` context (e.g. JetBrains → `editor::NewlineBelow`) can't shadow the bar's `agent::SelectPreviousThreadMatch`. Adds a regression test that loads `default-linux.json` + `linux/jetbrains.json` and asserts `shift-enter` navigates instead of inserting a newline. 7. `agent_ui: Debounce thread search, refresh on thread changes, highlight user messages`** — last round before maintainer review: 150 ms debounce on the match rescan; subscribe to `AcpThread` updates so results/highlights/counter follow a streaming conversation live; navigate the list to the entry owning the active match; `.ok()` instead of `let _ =`; assorted cleanups; two new regression tests (`test_thread_search_refreshes_on_new_thread_entry`, `test_thread_search_scrolls_to_later_user_message_match`). </details> 8 gpui tests cover the load-bearing logic (`cargo test -p agent_ui --lib -- thread_search`). All pass. ## Manual testing Verified on Linux against `upstream/main` `bde5c0bdc9` (full `release` profile, with LTO and `codegen-units=1` built and tested at that commit). Branch since merged with `upstream/main` `2106e8c`. Of the 100 intervening upstream commits, several touch files in this diff; one produced a real conflict in `crates/agent_ui/src/conversation_view.rs` (`gpui::{...}` import block — both sides added new, non-overlapping symbols; resolved by union). - Bar opens / dismisses via Ctrl+F and Esc - Next/prev navigation via Enter / Shift+Enter / F3 / Shift+F3 / chevron buttons - Case / whole-word / regex toggles via buttons and via Alt+C / Alt+W / Alt+R (Linux) - Highlights inside past user messages render correctly on the `MessageEditor`'s inner `Editor` - query text turns red on no-match; bad regex shows error message; zero-match counter stays muted (not red) - `search::*` actions fire from outside the bar (focus in message editor) via the `ThreadView`-level forwarders - Workspace pane `BufferSearchBar` is unaffected; the two bars hold independent state - Feature looks great in light mode and dark mode, and with various themes - Navigating to a match in a past user message scrolls that message into view (its top to the viewport top) - Results update live as the agent streams new messages while the bar is open (debounced ~150 ms, same for typing) [Zed agent thread search subscribe to thread updates.webm](https://github.com/user-attachments/assets/75585fee-ba25-42ac-9dde-16c8e152fb06) <details><summary>Full manual test plan</summary> ### Setup (preconditions for every test below unless otherwise noted) 1. Launch the dev binary: `./target/release-fast/zed --user-data-dir ~/.local/share/zed-dev-feat` 2. Open the agent panel, start a thread, send 2–3 prompts so the thread contains: - At least one user prompt with a distinctive substring (e.g. `watermelon`) - At least one assistant message with a distinctive substring - At least one tool call with a known label substring - At least one collapsed Thinking block 3. In parallel: have at least one code editor open in a workspace pane (some tests cross-check that path). ### Core matching #### T-001 — Ctrl+F opens the bar with focus in query **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** With focus in the agent panel's message editor, press Ctrl+F (Linux) / Cmd+F (macOS). The search bar appears at the top of the thread view and the query input is focused. #### T-002a — Active match visually distinct from inactive matches **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Type a query that produces ≥3 matches. The current ("active") match must be visually different from the others — different highlight color, not just position. If they look identical, this may be a theme issue (`search_active_match_background` vs `search_match_background` too close on the entry's background); note the theme. #### T-002b — User-prompt text gets inline highlight, not just match count **Status:** ✅ PASS 2026-05-15 17:15 (fix shipped 2026-05-15 16:15; regression-guarded by `test_thread_search_highlights_user_message_editor`) **Repro:** Send a user prompt containing a distinctive substring. Then search that substring. The user prompt text **must** show yellow highlight, not just be counted. The bar's matcher reads from `message.content.markdown()` but the on-screen render goes through a `MessageEditor`; the current code only highlights via `Markdown::set_search_highlights`, which misses the editor. **Notes:** Fix routes user-message matches through `Editor::highlight_background(HighlightKey::BufferSearchHighlights, …)` — the same path `Editor`'s own `SearchableItem` impl uses. `collect_markdowns` no longer pulls the user message's markdown (avoiding double-counting). The bar now maintains separate `highlighted_markdowns` and `highlighted_editors` lists for clean-up. Match-target enum (`MatchTarget::Markdown` vs `MatchTarget::Editor`) tags each match so active-vs-inactive re-paint can dispatch correctly. Pending runtime verification on next `release-fast` build. #### T-003 — Enter / Shift+Enter in bar navigates matches **Status:** ✅ PASS 2026-05-25 14:00 (verified on `release` build) **Repro:** With focus in the query, type a query with ≥3 matches. Press Enter → counter `1/N → 2/N → 3/N`. Press Shift+Enter → reverses (and no `\n`s are output in the search box). F3 / Shift+F3 same. ### Option toggles #### T-004 — Alt+C toggles case sensitivity from inside bar **Status:** ✅ PASS 2026-05-15 07:50 **Repro:** With focus in query, press Alt+C. `Aa` button toggles state; results re-filter. #### T-005 — Alt+W toggles whole-word from inside bar **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Same as T-004, with Alt+W toggling `wd` button. #### T-006 — Alt+R toggles regex from inside bar (Linux) **Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:35) **Repro:** Press Alt+R. `.*` button toggles. **Notes:** macOS keymap (`alt-cmd-x`) left unchanged in this session — it matches the wider macOS Zed convention. #### T-006a — Tooltips on toggle buttons show their hotkey **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Hover each toggle button (`Aa`, `wd`, `.*`). Tooltip shows action name AND keybinding (e.g. "Toggle Case Sensitive · Alt+C"). ### Error / empty states #### T-007 — Empty matches: no red border on bar input **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Type `zzzzzzz`. Query text turns red. Counter shows `0/0`. Bar input border stays **neutral**, no red box. #### T-008 — Bad-regex error message **Status:** ✅ PASS 2026-05-15 15:30 (error renders aligned with the input) **Repro:** Switch to regex mode, type `[`. Error message appears below bar, aligned with the input. #### T-019 — Zero-match counter not colored red **Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30) **Repro:** Type a query with no matches. The counter (`0/0`) stays muted, **not** red. MPS-parity. ### Dismissal & re-entry #### T-009 — Esc doesn't interrupt agent generation **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Start a long prompt; while the agent is generating, open the search bar and press Esc. Bar closes, generation continues. #### T-010 — Close-X button position **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Look at the bar. Close (X) button is on the right side, after the nav arrows (`<` `>` `1/N` `X`). NOT free-floating left of the input. #### T-011 — Ctrl+F in bar selects all query text **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** With bar open and query containing text, press Ctrl+F. All query text becomes selected (next keystroke replaces). #### T-012 — Ctrl+F outside the bar (bar already open) does not crash **Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 06:30; regression-guarded by `test_thread_search_select_next_from_thread_view_update_does_not_panic`) **Repro:** Bar visible, focus in the message editor (not the bar). Press Ctrl+F. Bar gets re-focused, query text is selected. **Must not crash.** **Notes:** Original crash also reproducible from Enter / Shift+Enter inside the bar after a search had matches. Fix wraps the `on_activate_match` callback's `view.update` in `cx.defer`. #### T-021 — Esc dismisses agent bar (not the unrelated workspace pane's BufferSearchBar) **Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 14:40; regression-guarded by `test_thread_search_editor_cancel_dismisses_bar`) **Repro:** Open a file in a workspace pane editor (e.g. `settings.json`). Open BufferSearchBar there. Switch focus to the agent panel, open agent search bar, type a query. Press Esc. **The agent bar must dismiss; the workspace pane's BufferSearchBar must remain.** **Notes:** Root cause: `Editor::cancel` in single-line mode calls `cx.propagate()`. The propagated `editor::actions::Cancel` walked past our bar all the way to `Workspace`, where `BufferSearchBar::register` had registered a workspace-wide handler that dismissed the active pane's bar. Fix: `ThreadView` now catches `editor::actions::Cancel` when the bar is visible. ### Action routing while bar is open, focus is in the message editor #### T-013 — F3 / Shift+F3 from outside the bar **Status:** ✅ PASS 2026-05-15 15:30 (Enter from outside is *expected* not to work — message editor's `enter` binding outranks. F3 is the canonical out-of-bar nav key.) **Repro:** Bar open with matches, focus in message editor. Press F3 → next match. Shift+F3 → previous. #### T-014 — Alt+C / Alt+W / Alt+R from outside the bar **Status:** ✅ PASS 2026-05-15 15:30 (fix shipped 2026-05-15 02:30; `ThreadView` forwarders for `search::ToggleCaseSensitive`, `ToggleWholeWord`, `ToggleRegex`, `FocusSearch`) **Repro:** Bar visible, focus in message editor. Alt+C/W/R toggles the bar's options and re-runs search. ### Nav buttons #### T-022 — `<` / `>` chevron buttons in the bar advance match **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** With ≥2 matches, click `<` → previous. Click `>` → next. Wraps at ends. ### Coexistence with workspace-pane buffer search #### T-015 — Ctrl+F in a workspace-pane editor still opens `BufferSearchBar` (no agent-panel takeover) **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Focus a code editor in a workspace pane, press Ctrl+F. The pane's `BufferSearchBar` opens as before; agent panel's bar does NOT open. #### T-016 — Independent bars: agent vs workspace pane **Status:** ✅ PASS 2026-05-15 15:30 **Repro:** Have both bars open simultaneously. They hold independent state (different queries, different toggles, independent dismissal). ### Tool-call content (auto-expand on match) #### T-017 — Auto-expand collapsed tool calls on match **Status:** ⏸️ BLOCKED (not implemented; out of scope for current session) **Repro:** Have a tool call whose collapsed content contains a unique substring. Search that substring. The tool call auto-expands so the match is visible. After dismissal, the tool call collapses again unless the user manually expanded it before. #### T-018 — Auto-expand collapsed Thinking blocks on match **Status:** ⏸️ BLOCKED (not implemented; out of scope for current session) **Repro:** Same shape as T-017 for a collapsed Thinking block. #### T-019 — Streaming results automatically highlighted / live thread search **Status:** ✅ PASS 2026-06-08 **Repro:** Send prompt "Write a 5-paragraph story about a researcher who hated noise. The last paragraph should be a one-sentence: "So she moved to <name of the quietest continent on Earth>" (replace that <name> with the actual name)", then search for `Antarctica`. </details> ## Known limitations 1. (pre-existing, not from this PR): search highlights inside markdown table cells can be visually offset by a few characters in columns starting with the second. The bug lives in `crates/markdown`'s render layer - see issue #57229 2. (excluded vs. #54816 to keep the scope tight): raw tool-call input/output JSON and terminal scrollback are not indexed. 3. Navigating to a search hit located **below the fold of a very long user message** highlights the match but only scrolls the message's top into view, so the hit can stay off-screen until you scroll manually. Past user messages render through an `AutoHeight` `Editor` inside a virtualized `List`, which can't reliably drive intra-entry autoscroll the way markdown content does. User messages are usually shorter than a viewport, so this is left unaddressed. 4. Plain-text search across triple-backtick fences does not match (the fence characters live in the markdown source; regex search with explicit fence handling does). 5. The literal text "Thinking" rendered as the thought-disclosure header is not searchable (rendered chrome, not markdown source). Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - No new `unsafe` introduced; no network, file-system, or process APIs touched; only added dep is `search` (promoted from dev-dep to runtime), already used by this crate's tests; `MessageEditor::editor()` accessor widening is `pub(crate)` (in-crate only). Assessment: no new attack surface. - [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) — partially; see "What I did NOT verify" above - [ ] I did not verify **macOS and Windows**. Keymap entries exist for all three platforms (`AcpThreadSearchBar` context bindings) but I only verified Linux at runtime. - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable: regexp-searching for "t.e" in a thread almost at the context limit (919k tokens) felt instant, and navigation among the 2100+ results occurred at the keyboard autorepeat rate. - [ ] Haven't measured against the 8ms / 120fps frame budget. Partially closes #39338 Release Notes: - Added in-thread search to the agent panel (Ctrl/Cmd+F) --------- Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de> |
||
|
|
e0f94ef984 |
git: Detect SCP remotes with non-standard SSH usernames (#59457)
# Objective The scp-style remote rewrite only treats a leading `user@` as SSH when the username matches `^[0-9a-zA-Z\-_]+@`. Remotes like `first.last@host:owner/repo.git` (common on self-hosted instances that authenticate as the developer) therefore fail to parse, so no hosting provider matches and Copy Permalink, git blame links, and Open in browser silently break. Extends #21508, which added `org-000000@`. ## Solution Match the scp username by exclusion (`^[^/@:]+@`): anything before the `@` that isn't the `:`/`/` delimiting host and path, mirroring git's scp syntax. The pattern stays anchored, so `scheme://user@host` URLs aren't misclassified, and it's a strict superset of the old one, so existing remotes are unaffected. ## Testing `cargo test -p git` passes, including two new `test_parsing_valid_remote_urls` cases — a dotted-username scp remote (the fix) and a `https://user@host` regression guard. `cargo fmt` and `cargo clippy -p git` are clean. ## 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 - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable --- Release Notes: - Fixed detection of SSH git remotes whose username contains characters such as `.` (e.g. `first.last@host:owner/repo.git`), which previously broke permalinks, git blame links, and "open in browser". --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
2321c03386 |
markdown_preview: Do not show deleted hunks (#59485)
Closes #55966 Release Notes: - Fixed an issue where deleted changes would show up in the markdown preview |
||
|
|
53597983aa |
fs: Dispatch watcher events from the reader thread to avoid thrashing (#59537)
On large worktrees, normal fs activity (like a `git checkout`) could send the file watcher in to a rescan thrash: we processed each event on the thread that reads events from the OS, and each event was checked against every watched directory. On big projects this was too slow to keep up, so the OS event buffer overflowed and dropped events, and a dropped event forces a full rescan - creating this unbounded loop. This PR moves dispatch onto a dedicated `fs-watcher-dispatch` thread. The reading thread now only drops `Access` events and forwards the rest, so it should stay fast enough to keep draining the kernel queue and bursty fs behaviour won't cause an overflow. In addition, we now index registrations by watched path. Instead of waking up every watched folder whenever any file changes anywhere, we now only wake up the folders that actually contain the changed file. Closes FR-31. Related to #57042. Release Notes: - Improved file watcher performance on large worktrees |
||
|
|
fb2e66f61b |
markdown_preview: Add max-width setting (#59512)
This PR introduces a markdown preview max-width setting in which we allow to limit by a given pixel number how wide the content within the preview tab should go. Before this, content would render edge-to-edge and if you're reading long markdown docs with no split panes, having it be full width like that was a horrible reading experience. So, right now, you can control that through the `zed://settings/markdown_preview.max_width` setting. <img width="600" alt="Screenshot 2026-06-18 at 1 24@2x" src="https://github.com/user-attachments/assets/7f0216e1-e4ac-47f7-975b-5de7a0dd4c6d" /> Release Notes: - Added setting to control max-width of content within the markdown preview. |
||
|
|
aed5023e80 |
git: Use fast access check for repository in git panel (#59514)
# Objective The git panel currently runs a full `git status` for checking whether `git` has access to the repository. This was introduced in #43693 and currently runs on every file save which is problematic for large repos where `git status` runs a lot of computation. ## Solution This PR switches to a simple `git rev-parse` command which is cheap and achieves the same goal. ## Testing I added a unittest. ## 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 /cc @dinocosta Release Notes: - Improve performance of git access checks in git panel |
||
|
|
21a80e7a53 |
perf: Add initial benchmark for markdown element (#59524)
## Summary This PR adds an initial markdown element renderer benchmark, so we could later expand this to benchmark search in markdown, and reparsing. This is important because the agent panel renders a lot of markdown elements, so I want to use these benchmarks to ensure our markdown element performance is good, and later expand them to include the agent panel I added a `bench_util.rs` file that has methods to generate random rust modules, this will later be used by the editor benchmarks, and is currently used by the markdown and edit_file_tool benchmarks. Finally, I made `cx.bench_renderer` also account for ready foreground tasks and poll them. This more accurately mimics gpui dispatcher. (It's not perfect, but it's good enough for a benchmark) ## 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 --------- Co-authored-by: Anant Goel <anant@zed.dev> |
||
|
|
29f031d4d9 |
Support slashes in selected model IDs (#59523)
Summary: - Parse selected model identifiers at the first slash so model IDs may contain additional slashes. - Add regression coverage for slash-containing model IDs and invalid identifiers. Testing: - `cargo test -p language_model selected_model_ --lib` Release Notes: - Fixed selecting custom language models whose model IDs contain slashes. |
||
|
|
875363a186 |
Fix opening folders whose name ends in a position-like suffix (#59384)
## Objective
Dragging a folder onto the Zed dock icon (or otherwise opening it by
path) failed
when the folder's name ended in a parenthesized number, e.g. `Test (1)`
or `Test (2,3)`. Instead of opening the folder, Zed opened a
non-existent, truncated path (`Test `), so nothing useful appeared.
The cause is `PathWithPosition::parse_str`, which supports MSVC-style
position
suffixes like `file.c(22)` → file `file.c`, row `22`. A folder named
`Test (1)`
was therefore parsed as path `Test ` at row `1`.
`derive_paths_with_position` has
a guard that restores the literal path when it exists on disk — but it
only
checked `fs.is_file(...)`, so directories never qualified and the
truncated path
was used.
## Solution
In `derive_paths_with_position`, restore the original path when it
points to an
existing file **or directory** (`fs.is_file(...) || fs.is_dir(...)`),
instead of
files only.
## Testing
- Added
`test_derive_paths_with_position_directory_with_position_like_name`,
which
opens `Test (1)`, `Project (2,3)`, and `test project` directories and
asserts the full paths survive with no row/column.
- Added `test_parse_str_treats_paren_suffix_as_position` in `util`
documenting the
underlying `parse_str` behavior that necessitates the guard.
- Manually verified on macOS: built a debug `Zed Dev.app`, dropped
folders named
`Test (1)` onto the dock icon — it now open correctly;
previously a non-existent folder was opened.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments — N/A, no unsafe
- [ ] The content adheres to Zed's UI standards — N/A, no UI change
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable — one
extra `is_dir`
stat only when a path parses to a row and differs from the original
---
Release Notes:
- Fixed folders whose names end in a parenthesized number (e.g. `Test
(1)`) failing to open from the dock or by path
|
||
|
|
2cb3ee0947 |
Enable sandboxing for staff by default (#59507)
Enable the existing agent sandboxing feature flag for staff by default, so staff builds use sandboxed terminal commands without needing an explicit flag override. Release Notes: - N/A --------- Co-authored-by: Martin Ye <martin@zed.dev> |
||
|
|
2695485be4 |
Add global setting to enable or disable the agent sandbox (#59497)
Adds a global `agent.sandbox_permissions.enabled` setting (defaulting to on) that controls whether agent-run terminal commands are wrapped in an OS-level sandbox, and surfaces it as an Enable Sandbox toggle at the top of the sandbox settings page. When the toggle is off, the rest of the sandbox settings UI is hidden, and `sandboxing_enabled` now requires both the existing feature flag and this setting so commands actually run unsandboxed. Because the setting defaults to `true` rather than `false`, the compiled `SandboxPermissions` gets a manual `Default` impl instead of the derived one. Release Notes: - Added a setting to enable or disable the agent terminal sandbox, toggleable from the agent sandbox settings page. |
||
|
|
92d9a8b356 |
Add Windows terminal sandboxing via WSL (#58971)
Summary - Adds Windows agent terminal sandboxing by routing commands through WSL and Bubblewrap. - Supports native Windows and WSL project paths, including elevated write grants for WSL paths. - Shows a confirmation prompt to turn off sandboxing when WSL sandbox setup is unavailable. This builds on the work in the sandbox-linux branch. Closes AI-376 Release Notes: - Added Windows terminal sandboxing for agent commands when sandboxing is enabled. --------- Co-authored-by: cameron <cameron.studdstreet@gmail.com> Co-authored-by: Richard Feldman <oss@rtfeldman.com> Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
da7b0f68b1 |
Bump alacritty_terminal repo SHA (#59445)
See https://github.com/zed-industries/alacritty/commit/4c129667ce56611becdc82de6e28218c80e2e88f. The main change here is making `set_nonblocking` return `Result` rather than panicking. Closes FR-78. Release Notes: - N/A |
||
|
|
adb6a5c1f2 |
open_path_prompt: Cancel in-flight tasks when dialog is dismissed (#59423)
Closes FR-79. Release Notes: - Improved delegate behaviour when dismissing `Open Path` prompt |
||
|
|
d25d2639df |
markdown: Add debug_asserts for search result ordering (#59483)
Follow up to #59473 The previous code could actually highlight the wrong match if you passed in unordered ranges. However, i realized that all codepaths are passing in ordered matches already, so I just added some `debug_asserts` to ensure that this is always the case. Release Notes: - N/A |
||
|
|
7539fb0913 |
Move the crash handler process spawn to a background thread (#58881)
Moves the crash handler subprocess spawn off the main thread to speed up startup, especially on Windows where process creation is slower. Previously `crashes::init` did part of its work synchronously when it was *called*, including `spawn_crash_handler`, which launches the `zed --crash-handler` child process (a synchronous `CreateProcessW` on Windows). Because `init` is evaluated inline as the argument to `background_executor().spawn(crashes::init(...))` in `main.rs`, that subprocess spawn ran on the main thread during startup rather than on the executor. This PR makes `connect_and_keepalive` a fully `async fn`, so all of that work, including the subprocess spawn, now runs on the background executor instead of blocking the main thread. I don't have a Windows machine to capture before/after numbers, but the crash handler spawn is clearly on the startup critical path. Logs in the Windows slow startup reports show it taking ~100–700ms between `spawning crash handler process` and `connected to crash handler process` (e.g. #40621, #54856), all of which previously blocked the main thread. Related to #49442 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: - Improved startup performance |
||
|
|
d9082eeda1 |
Add harden-runner in audit mode to run_tests Linux jobs (#59446)
## What Adds `step-security/harden-runner` as the first step of the Linux Namespace jobs in `run_tests.yml`, running in audit mode (`egress-policy: audit`). In audit mode it records each job's outbound network connections and blocks nothing — there is no change to what the jobs can do. Pinned to `step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411` (v2.19.4); v2.19.0+ is required for Namespace runners. Each run links to its per-run insights from the job log. ## Scope - **Included:** the 13 Linux Namespace jobs in `run_tests.yml`. - **macOS excluded:** harden-runner's monitoring agent is Linux-only on Namespace runners — it skips install on Namespace macOS, so it adds no coverage there and its cleanup step fails. - **Also not included:** the Windows jobs, the `tests_pass` gate (no checkout, no egress to record), and the `extension_tests` reusable-workflow call. - The shared job builders (`clippy`, `run_platform_tests`, `check_scripts`, `orchestrate`) are reused by other workflows, so they take a flag to add the step only in the `run_tests` context. `release.yml`, `release_nightly.yml`, and `extension_tests.yml` are unchanged. ## How Edits the workflow DSL under `tooling/xtask/src/tasks/workflows/`; the YAML is regenerated with `cargo xtask workflows`. ## Verification - `cargo xtask workflows` is idempotent — the `check_scripts` parity check passes. - `cargo fmt --check` and `actionlint` clean; `zizmor` shows no new findings vs. baseline. Release Notes: - N/A --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
f6512349ff |
a11y: Settings UI (#59429)
Adds: - aria attributes to most UI elements in settings UI - a new a11y API to GPUI - a fix for a GPUI keyboard focus bug ## Accesible settings UI Settings UI should now be fully accessible to users of assistive technology. **However**, there are some caveats: - accessibility features require zed to be launched with the `ZED_EXPERIMENTAL_A11Y=1` env var to be set - I have not exhaustively checked every control - There are some quite surprising keyboard focus behaviours which predate this code - The main Zed UI is still largely inaccessible, though a handful of shared components will now report themselves, but the experience is suboptimal. For anyone wishing to try out the settings UI: - make sure `ZED_EXPERIMENTAL_A11Y=1` is set - open zed - press `ctrl-,` (or `cmd+,` on a mac) to open settings UI in a separate window ## `aria_active_descendant` This is equivalent to the [`aria-activedescendant`](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-activedescendant) API on the web. It allows a container to maintain focus, while indicating that one of its children should be active. Zed uses this for menus and combo boxes, for example. GPUI will report a div with `.aria_active_descendant()` as long as: - an ancestor is focused - only one descendant of the focused ancestor has `.aria_active_descendant()` Two descendants with this property where the focused node is a common ancestor is an error. ## GPUI keyboard fix GPUI will map a space or enter keypress to a div's `on_click` handler, if it exists. However, the keyboard-driven path was missing some checks that the mouseclick path has. With this PR, for an enter/space keypress to be considered a click, between the "key down" and "key up" events: - there must be no other key events - focus must not move to a different node This fixes an existing bug with combo boxes in zed where: - enter maps to `menu::Confirm` **on key down* - the menu item is selected - focus moves to the combo box - enter then triggers the combo box's `on_click` **on key up**, re-opening the menu --- Release Notes: - N/A or Added/Fixed/Improved ... --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
381dc0bbe3 |
language_models: Clear speed for OpenAI-compatible providers that don't support fast mode (#59496)
`OpenAiCompatibleLanguageModel::stream_completion` (used for custom OpenAI-compatible providers) forwarded `request.speed` straight into `into_open_ai`/`into_open_ai_response`, which translate `Speed::Fast` into OpenAI's `service_tier` field. Custom OpenAI-compatible endpoints don't recognize that field and reject the request. `speed` can end up set even for a provider that doesn't support fast mode: `Thread::inherit_parent_settings` copies `speed` from a parent thread to a subagent without checking whether the subagent's model supports it. Every other provider sharing this conversion code already guards against this (`open_ai.rs`, `anthropic.rs`, `anthropic_compatible.rs`, `language_models_cloud.rs`). This adds the same guard for `OpenAiCompatibleLanguageModel`. Release Notes: - Fixed requests to OpenAI-compatible providers (e.g. Baseten) sometimes including an unsupported `service_tier` parameter |
||
|
|
c3f6870451 |
Periodically log memory usage (#58999)
In recent memory leak reports the log was lost (OS killed Zed or forced a reboot) or showed nothing about when memory grew, leaving us unable to correlate growth with LSP/toolchain activity in the log. This should help diagnose: - https://github.com/zed-industries/zed/issues/58987 - https://github.com/zed-industries/zed/issues/58662 - https://github.com/zed-industries/zed/issues/31461 The polling costs one single-PID, memory-only sysinfo refresh (roughly one syscall) every 30s — less than the existing per-language-server polling in `lsp_button.rs`. So the overhead of this shouldn't affect performance of Zed. 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 |
||
|
|
34f0cc9207 |
ci: Publish static bubblewrap in releases (#59488)
Adds a step to the release and run_bundling workflows to build a statically-linked bubblewrap binary and upload it --- Release Notes: - N/A or Added/Fixed/Improved ... --------- Co-authored-by: Tom Houlé <tom@tomhoule.com> |
||
|
|
6d6641b194 |
Add agent sandbox permissions settings page (#59448)
Adds a dedicated Sandbox settings page under the AI settings, letting users review and manage the elevated terminal sandbox permissions that are always allowed without prompting. The page exposes: - Network: an "Allow All Domains" toggle and an editable list of allowed domains (exact domains or leading-`*.` subdomain wildcards), with validation. - Filesystem: an "Allow All Filesystem Writes" toggle and an editable list of writable paths. - Sandbox: an "Allow Unsandboxed Terminal Commands" toggle. This replaces the single "Allow Unsandboxed Terminal Commands" setting item with the new page, and updates the agent panel's settings shortcut to open it. "Allow always" sandbox grants now persist to settings only and are no longer also cached as an in-memory thread grant. Closes AI-413 Release Notes: - Added a settings page for managing the agent terminal sandbox permissions (allowed domains, writable paths, and unsandboxed command execution). |
||
|
|
d489d6c987 |
agent: Account for max_output_tokens in compaction threshold (#59469)
Follow up to #58883 This makes sure that we subtract the max output tokens before checking the threshold for auto compaction was reached, we had that logic before #58883 but we lost it when introducing the settings. Without this GPT models will run out of tokens before auto-compaction is run Release Notes: - (Preview only) Fixed an issue where auto compaction would not be triggered |
||
|
|
2df978b11c |
markdown: Optimize paint_search_highlights (#59473)
Follow up to #52502 This fixes a severe hang in the markdown preview when searching for text caused by `paint_search_highlights`. We were iterating over all lines for each highlight, and for each highlight we called `layout.line_layout_for_index` which internally would iterate over all the lines of the text layout. With this optimisation we paint all highlights in one pass. We sort the highlight ranges, iterate through the lines and only access `WrappedLineSegments` when we actually have a highlight in that line. E.g. if you copy this text (https://gist.github.com/bennetbo/e313f3023da9fec42e090177a5373152) into the editor, open the markdown preview and search for `codex` Zed Nightly will completely freeze. After this optimisation it is totally smooth even in debug mode. Release Notes: - Improved performance when searching in markdown preview |
||
|
|
76f258b504 |
Refactor editor's select inside/around delimiter actions (#59472)
# Objective Both https://github.com/zed-industries/zed/pull/59005 and https://github.com/zed-industries/zed/pull/53789 introduced actions, at the editor context, which allow to select the content between brackets/delimiters, with the latter also adding an action to include the brackets/delimiters too. Shipping both would mean we end up with three distinct, but similar actions: * `editor: select inside enclosing bracket` * `editor: select inside delimiters` * `editor: select around delimiters` As such, in order to simplify this, the changes in this Pull Request remove the first action, while updating the logic for both `editor: select inside delimiters` and `editor: select around delimiters` in order to support continuous outwards expansion, like `editor: select inside enclosing bracket` supported. ## Solution * Remove `editor::SelectInsideEnclosingBracket` action, it's related method and tests * Updated `editor::selection::Editor::select_delimiters_impl` to use `MultiBufferSnapshot::enclosing_bracket_ranges` instead of `MultiBufferSnapshot::innermost_enclosing_bracket_ranges` so we can traverse all bracket ranges and expand to the next one ## Testing Besides manual testing, a new test case was added specifically for the selection expansion support, namely `editor::editor_tests::test_select_delimiters_expansion`. ## 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 |
||
|
|
afa22f66fe |
editor: Add SelectInsideDelimiters and SelectAroundDelimiters actions (#53789)
## Summary
Adds two new editor actions:
- `editor::SelectInsideDelimiters`: selects the content inside the
nearest enclosing delimiters. Works for `()`, `[]`, `{}`, and string
literals (`""`, `''`, `` ` ` ``).
- `editor::SelectAroundDelimiters`: same as above, but the selection
includes the surrounding delimiters themselves.
This addresses the request in #50042
## Why not `select_larger_syntax_node`?
`SelectLargerSyntaxNode` walks up the AST one level at a time. It's an
incremental, history-aware operation: press repeatedly to expand outward
by syntax tree level. The number of presses needed to reach a specific
delimiter pair depends on the language's AST shape and is unpredictable:
sometimes one press, sometimes three, sometimes overshoot.
`SelectInsideDelimiters` is delimiter-based and stateless: one
invocation jumps directly to the nearest enclosing pair, regardless of
AST nodes. It's the equivalent of Vim's `vi(`, `vi{`, `vi"` text
objects, available without requiring Vim mode. The two actions solve
different problems.
## Implementation
Both actions use
`MultiBufferSnapshot::innermost_enclosing_bracket_ranges`, which already
handles nesting, multi-buffer excerpts, and language-specific bracket
definitions, including languages where quotes are declared as bracket
pairs (Rust, Python, JavaScript, JSON, etc.).
For string-like content where the language does not register quotes as
brackets (notably Markdown inline content), `SelectInsideDelimiters`
additionally falls back to a `syntax_ancestor` check for tree-sitter
node kinds `string_content` and `inline`. This is the same set of node
kinds already used in `select_larger_syntax_node`.
Multi-cursor support comes from `move_offsets_with`.
## Tests
Two new tests in `editor_tests.rs` covering:
- Basic delimiter selection (parens, brackets, braces)
- Innermost detection with nested pairs
- String content selection (TypeScript)
- Selection expansion when starting from an existing selection
- No-op when cursor is not inside any delimiter
## Notes
No default keybindings are provided. Users can bind via their keymap.
Can add defaults if reviewers prefer.
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 #50042
Release Notes:
- Added `editor::SelectInsideDelimiters` and
`editor::SelectAroundDelimiters` actions for selecting content within
the nearest enclosing brackets, braces, parentheses, or quotes.
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
|
||
|
|
2bdbd0ef18 |
editor: Reuse display-map cursors when converting word diffs (#58658)
layout_word_diff_highlights converted each visible word diff to display points via isomorphic_display_point_ranges_for_buffer_range, which walks the inlay/fold/tab/wrap/block trees from the root on every call. With many word diffs on screen this re-walks the same trees repeatedly each frame. Add a DisplayPointConverter that holds a forward-only cursor for each display-map layer (mirroring the cursor reuse already done in BlockMap::sync) so consecutive conversions amortize to near-constant work. New forward cursors BufferOffsetToInlayPointCursor and BlockPointCursor back the inlay and block layers; the fold/tab/wrap layers reuse existing cursors. Each cursor gains a cheap reset() that delegates to the underlying SumTree cursor; the converter resets its cursors if an input range starts before the previous one ended, so it stays correct for overlapping inputs (e.g. the base and buffer word diffs of an inline modified hunk). layout_word_diff_highlights now sorts the visible word diffs and feeds them through a single converter. isomorphic_display_point_ranges_for_buffer_range is reimplemented on top of the converter to keep one code path. Release Notes: - Improved scrolling performance in diff views containing large hunks |
||
|
|
a41ccd1206 |
editor: Speed up multi cursor editing (#58510)
Early draft for #32051 (multi-cursor editing is very slow, and basically hangs at high cursor counts). Opening it early like @Anthony-Eid suggested so we can agree on direction before I go further. ## Root cause Typing with a cursor on every line is mostly O(N)-per-keystroke work spread across a few places. I profiled it with `sample` and per-phase timers around `handle_input`. At 1000 cursors (~24ms before this PR): the post-edit display-map sync is ~11.8ms, the CRDT edit (`apply_local_edit`) ~3.7ms, resolving all N selections plus the per-cursor input loop ~3.5ms, the post-edit selection round-trip ~2.6ms, and `change_selections` plus transact machinery ~2.4ms. The display sync re-runs per-edit `SumTree` work through every layer even when nothing transforms (the plain-text case), and selections get re-resolved through the full display round-trip several times per keystroke. ## What this does - Display fast paths: `InlayMap::sync` (no inlays) and `WrapMap::interpolate` (no soft-wrap) skip the O(edits) transform-tree rebuild and return the passthrough snapshot, gated so a pending inlay splice or existing wraps still take the slow path. - Selection fast path: when nothing collapses buffer content (`!has_folds() && !has_replacement_blocks()`), resolve `Anchor` to `Point` to `Offset` batched and skip the per-selection display round-trip (the `todo(lw)`). - Render and autoscroll resolve only the first/last/newest selections instead of all N per frame. - A parameterized `Multi-cursor input/cursors/{1000,10000,100000}` benchmark. ## Results - Typing (`handle_input`): ~2.1x faster (24ms to 11.7ms at 1k). - Type plus two word-deletes (criterion): 29% faster (89.9 to 63.8ms) at 1k, 37% (959 to 606ms) at 10k. - Post-edit display sync alone: 11.8 to 3.8ms at 1k, 133 to 45ms at 10k. All `editor` (759), `display_map` (67), `multi_buffer` (58), and `text` (36) tests pass, and `./script/clippy` is clean. ## Direction This is ~2x, and I can get the current architecture to roughly 3.5-4.5x with a few more safe changes (hoisting the per-cursor language/editability checks, cheaper snapshot clones). Genuine VS Code numbers (~1-2us/cursor) aren't reachable while the buffer is a CRDT rope of fragments with anchor selections and a 5-layer transform stack. That would need a plain-offset cursor model and/or decoupling display layout from the edit path, which is a bigger effort I'd want to design with you. One thing I'd need your call on: `set_active_selections` sends an `UpdateSelections` collab op every keystroke (building N anchors); can that be debounced to transaction end, or do presence/follow-mode features rely on per-keystroke cursor broadcast? Release Notes: - editor: Improved multi cursor editing performance --------- Co-authored-by: Anthony Eid <anthony@zed.dev> |
||
|
|
5bdcb12042 |
Fix project grouping for Git repo subdirectories (#57998)
Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] Unsafe blocks (if any) have justifying comments - No unsafe blocks added. - [x] The content is consistent with the [UI/UX checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) - No new UI components; behavior better matches user intent for opened folders. - [x] Tests cover the new/changed behavior - Added sibling-subdirectory project group regression coverage. - Extended subfolder Git-status test to ensure Git still uses the parent repo while project identity stays at the opened folder. - [x] Performance impact has been considered and is acceptable - Change adds one small enum/optional field check when computing worktree paths; no meaningful performance impact expected. Closes #57997 Release Notes: - Fixed project grouping for opened subdirectories that share the same parent Git repository. ## Screenshots ### Before <img width="334" height="224" alt="Screenshot 2026-05-28 at 5 29 55 PM" src="https://github.com/user-attachments/assets/ad5b13c5-11a7-4fa4-a074-a519521641da" /> <img width="485" height="201" alt="Screenshot 2026-05-28 at 5 28 36 PM" src="https://github.com/user-attachments/assets/9cd2c138-92f5-4ff2-bf8f-21cdbeff0b79" /> ### After <img width="343" height="253" alt="Screenshot 2026-05-28 at 5 29 40 PM" src="https://github.com/user-attachments/assets/56a4dca7-f0a1-4530-8c89-3c4773b90486" /> <img width="420" height="206" alt="Screenshot 2026-05-28 at 5 29 22 PM" src="https://github.com/user-attachments/assets/d118340a-955e-4483-9888-4b566f59b931" /> --------- Co-authored-by: Anthony Eid <anthony@zed.dev> Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com> |
||
|
|
3c1a24b269 |
Add terminal thread init command (#59374)
## Summary - Adds an `agent.terminal_init_command` setting for Terminal Threads. - Runs the configured command automatically when creating a new Terminal Thread, while skipping restored terminal threads. - Documents the setting and exposes it in the AI settings page. Closes https://github.com/zed-industries/zed/issues/58697 Closes AI-337 Release Notes: - Added a setting to automatically run a command when opening a new terminal thread in the agent panel. --------- Co-authored-by: Anant Goel <anant@zed.dev> |
||
|
|
377f28d1fc |
sidebar: Add submenu to create a worktree (#59341)
Closes AI-403 Recently, we introduced the ability to pick, from the plus icon button in a project's header in the sidebar, which of the currently loaded worktree you'd like to create a new thread on. This PR extends this ability by allowing you to _create_ a new worktree from there as well. Turned out this just felt like a natural move after playing around with the change internally; we had a good amount of internal asks for this. What's exposed in the menu is exactly the same options available in the worktree picker, following the same display rules. <img width="650" alt="Screenshot 2026-06-15 at 12 22@2x" src="https://github.com/user-attachments/assets/ef45d93e-9106-46c6-9a8b-bc099036a7de" /> Release Notes: - Agent: Enabled creating a new worktree from the sidebar's "new thread" icon button. |
||
|
|
0361eff982 |
editor: Refresh active debug line highlight on theme change (#59274)
# Objective Fixes #58736 Pause the debugger on a breakpoint, switch your theme, and the active debug line keeps its old highlight color until you step again or restart Zed. ## Solution The highlight stores a concrete color grabbed from the theme back when `go_to_active_debug_line` ran. A theme switch goes through `theme_changed`, which refreshes brackets, semantic tokens, and outline symbols but never re-applies that highlight, so it stays stale. Re-running `go_to_active_debug_line` from `theme_changed` re-resolves the color against the current theme. ## Testing Added a regression test in `debugger_ui` that stops at a debug line, swaps the theme's `editor.debugger_active_line.background`, and checks the highlight follows. It fails on `main` and passes with the fix. Also tested by hand on Windows: started a debugpy session, paused at a breakpoint, switched themes from the theme selector, and watched the active line recolor live without stepping or restarting. ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [x] 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 - [x] Performance impact has been considered and is acceptable ## Showcase Paused at a breakpoint, switching themes from the theme selector. | Before | After | | --- | --- | | https://github.com/user-attachments/assets/653a7e1b-3a99-4316-b1c9-b16ed7a7a8ba | https://github.com/user-attachments/assets/22a4c876-30f2-44c5-aad9-0f860639074c | --- Release Notes: - Fixed the active debug line color not updating when switching themes while the debugger is paused ([#58736](https://github.com/zed-industries/zed/issues/58736)). --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
2026946c10 |
Qwen prompt format (#59150)
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 Closes #ISSUE Release Notes: - N/A or Added/Fixed/Improved ... --------- Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com> |
||
|
|
47dd63518c |
ep: Store rejected patch as prediction (#59440)
# Objective - Describe the objective or issue this PR addresses. - If you're fixing a specific issue, use "Fixes #X" for each issue as [described in the GitHub docs](https://docs.github.com/en/issues/tracking-your-work-with-issues/using-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword). ## Solution - Describe the solution used to achieve the objective above. ## Testing - Did you test these changes? If so, how? - Are there any parts that need more testing? - How can other people (reviewers) test your changes? Is there anything specific they need to know? - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? ## 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 > This section is optional. If this PR does not include a visual change or does not add a new user-facing feature, you can delete this section. - Help others understand the result of this PR by showcasing your awesome work! - If this PR includes a visual change, consider adding a screenshot, GIF, or video - A before/after comparison is very useful for changes to existing features! While a showcase should aim to be brief and digestible, you can use a toggleable section to save space on longer showcases: <details> <summary>Click to view showcase</summary> My super cool demos here </details> --- Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
5c5ff37936 |
agent: Better sandboxing UI (#59437)
Adds UI for the various scenarios where sandboxing can fail on linux: - no `bwrap` on the path - `bwrap` is setuid - `bwrap` exists but cannot create unprivileged userns --- Release Notes: - N/A or Added/Fixed/Improved ... --------- Co-authored-by: Martin Ye <martin@zed.dev> |
||
|
|
d89fc86740 |
markdown: Render soft breaks as line breaks in agent markdown (#57376)
Agents sometimes output status lists with bullets represented by emojis - see #57372. These currently get rendered on one line, as opposed to bullet items like `-` or `*`, because single newlines within a paragraph are collapsed into spaces - standard CommonMark soft-break behavior *in prose* contexts (e.g. `README.md`). But in *comment/PR* contexts, GitHub preserves these newlines: ✅ Did A ✅ Did B ✅ Did C Users reasonably expect agent output to be rendered following the comment-style convention. ## What this PR does This PR adds a `soft_break_as_hard_break: bool` field on `MarkdownStyle` and enables it for `MarkdownFont::Agent`, so a single newline within a paragraph *in agent output* renders as a line break instead of a space. The field defaults to `false` to preserves CommonMark behavior everywhere else. In `themed_with_overrides`, sets it to `true` for `MarkdownFont::Agent`. The rendering switch in `MarkdownElement::request_layout` then emits `"\n"` instead of `" "` for `MarkdownEvent::SoftBreak` when the flag is set. This matches GitHub comments and Obsidian default behavior, and prevents emoji + trailing newline content from being collapsed onto a single line in agent responses. Scoped strictly to `MarkdownFont::Agent`. Hover popovers, diagnostics, markdown preview, README rendering, etc. are all untouched. 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) - [ ] Tests cover the new/changed behavior - visual tests completed: <img width="892" height="632" alt="image" src="https://github.com/user-attachments/assets/1aacb5da-edc8-49fd-bfe9-d37a22ae2d3f" /> - [x] Performance impact has been considered and is acceptable Closes #57372 Release Notes: - Improved agent panel markdown rendering: single newlines within agent responses now render as line breaks, matching the convention used by GitHub comments and Obsidian. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
b51bbef15b |
Ping on slack when a community-related workflow fails (#59435)
Release Notes: - N/A |
||
|
|
3cdbdeaaa3 |
Fix copy shortcut in macOS notebook cells (#59431)
Fix `cmd-c` not copying text inside macOS notebook cell editors. Previously, the macOS notebook keymap bound `cmd-c` to `notebook::InterruptKernel` in notebook contexts, including `NotebookEditor > Editor`. This shadowed the normal editor copy shortcut while editing notebook cells. ## Solution Move the macOS notebook interrupt shortcut from `cmd-c` to `ctrl-c`. This keeps the notebook interrupt shortcut available while allowing the normal editor keybindings to handle: - `cmd-c` for copy - `cmd-x` for cut - `cmd-v` for paste inside notebook cell editors. - This change is macOS-specific. Release Notes: - N/A --------- Co-authored-by: dino <dinojoaocosta@gmail.com> |
||
|
|
29aaa2e315 |
markdown_preview: Restore preview panes on workspace reload (#56972)
Markdown preview tabs were lost on restart because `MarkdownPreviewView` implements `Item` and `SearchableItem` but never opted into `SerializableItem`, so the workspace serializer silently skipped it. This change adds persistence, modeled on the existing `ImageView` and `Editor` patterns: - Add a `persistence` submodule storing `(workspace_id, item_id, abs_path, mode)` in a `markdown_previews` table. - `serialize` records the active editor's file path and the preview mode. `deserialize` reopens the file as a buffer and constructs a new `MarkdownPreviewView` around it. - Register the item type in `markdown_preview::init`. Untitled markdown buffers and previews whose source file no longer exists are not restored — `serialize` and `deserialize` return `None` and `Err` respectively, mirroring `ImageView`. `csv_preview` and `svg_preview` have the same `SerializableItem` defect; left out of this PR to keep scope focused. Closes #38581 Part of #7371 Release Notes: - Fixed Markdown preview tabs not being restored when reopening a workspace 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) - [ ] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable on the no tests bit, consistent with ImageView, ComponentPreview, GitGraph, TerminalView, and every other SerializableItem impl other than Editor. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com> |
||
|
|
fdebc23ccc |
Prevent archival of manually-created worktrees (#58275)
This fixes archive cleanup for agent threads so Zed only removes worktrees it explicitly created, rather than treating every linked worktree under the configured managed directory as safe to delete. When Zed creates a worktree, it now records it in the local database along with the creation time of the worktree's git metadata directory (`.git/worktrees/<name>/`). Archive planning requires that record, and right before deleting anything, Zed re-stats the directory and compares creation times: if the worktree was removed and recreated outside Zed (or the time can't be read at all), deletion is skipped and the stale record is dropped. Every failure mode fails safe by leaving the directory untouched. For remote (SSH) projects, the stat runs on the remote host via a new `GitWorktreeCreatedAt` request. Worktrees created by a different Zed install (another release channel, or another machine connecting to the same host) have no record in the local database and are therefore never auto-archived, which is the intended conservative behavior. Closes https://github.com/zed-industries/zed/issues/57155 Closes AI-352 Release Notes: - Fixed archiving an agent thread incorrectly deleting manually-created git worktrees. |
||
|
|
506792b895 |
Duplicate Bot: Switch to structured tool output for Claude (#59432)
Rather than continuing to try to persuade Claude to pretty please only output json, or to parse json out of Claude's prose, switch to forced tool calls with a json schema and hope this works better. And bump the version of the bot to 4 since the model upgrade which was shipped earlier today is evidently behaving differently enough. Release Notes: - N/A |
||
|
|
1b61228523 |
Settings UI agent providers (#58876)
Manage various LLM settings (previously in agent panel) in settings UI. Behind a feature flag, not staff shipped Release Notes: - N/A or Added/Fixed/Improved ... |
||
|
|
c835bc1b30 |
ci: Revalidate zed.dev after release (#59422)
Updates CI to use the revalidate mechanism for updating zed.dev post release, instead of doing a full re-deploy. Release Notes: - N/A |
||
|
|
09415bf9e5 |
Include changed paths in remote UpdatedEntries events (#58157)
Include the changed paths in `UpdatedEntries` events emitted by remote worktrees. Previously a remote worktree emitted `Event::UpdatedEntries` with an empty changeset (`Arc::default()`), discarding the changed paths. The changeset now carries the real added/updated/removed paths, resolving removed entries against the previous snapshot. Release Notes: - Fixed file change events not reporting changed paths in remote projects |