Commit Graph
38562 Commits
Author SHA1 Message Date
Edward Compton 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
2026-06-18 15:34:43 +00:00
davidhi7anddino 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>
2026-06-18 14:50:31 +00:00
Bennet Bo Fenner 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
2026-06-18 14:48:10 +00:00
zed-zippy[bot] 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>
2026-06-18 14:21:17 +00:00
( Nechiforel David-Samuel ) NsdHSOanddino 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>
2026-06-18 14:10:00 +00:00
MartinYe1234 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.
2026-06-18 13:24:24 +00:00
Dan DascalescuandBennet Bo Fenner 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>
2026-06-18 13:00:24 +00:00
Ibrahim Khananddino 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>
2026-06-18 12:52:51 +00:00
Bennet Bo Fenner 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
2026-06-18 12:48:18 +00:00
Neel 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
2026-06-18 11:17:06 +00:00
Danilo Leal 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.
2026-06-18 10:54:13 +00:00
Lukas Geiger 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
2026-06-18 07:47:47 +00:00
Anthony EidandAnant Goel 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>
2026-06-18 02:47:10 +00:00
Anant Goel 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.
2026-06-18 01:57:20 +00:00
Yan Khachko 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
2026-06-17 23:20:42 +00:00
Richard FeldmanandMartin Ye 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>
2026-06-17 22:42:46 +00:00
Richard Feldman 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.
2026-06-17 22:06:49 +00:00
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>
2026-06-17 21:07:29 +00:00
Neel 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
2026-06-17 19:12:24 +00:00
Neel 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
2026-06-17 19:12:16 +00:00
Bennet Bo Fenner 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
2026-06-17 18:53:29 +00:00
Anthony Eid 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
2026-06-17 18:29:21 +00:00
John D. Swansonandzed-zippy[bot] 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>
2026-06-17 18:06:59 +00:00
Cameron Mcloughlinandzed-zippy[bot] 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>
2026-06-17 17:42:38 +00:00
Anant Goel 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
2026-06-17 17:35:47 +00:00
Anthony Eid 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
2026-06-17 17:19:20 +00:00
Cameron McloughlinandTom Houlé 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>
2026-06-17 15:03:03 +00:00
MartinYe1234 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).
2026-06-17 14:59:09 +00:00
Bennet Bo Fenner 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
2026-06-17 11:56:44 +00:00
Bennet Bo Fenner 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
2026-06-17 11:48:13 +00:00
Dino 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
2026-06-17 10:37:40 +00:00
subeaxanddino 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>
2026-06-17 10:06:42 +00:00
Lukas Wirth 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
2026-06-17 08:39:02 +00:00
RaniandAnthony Eid 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>
2026-06-17 07:57:05 +00:00
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>
2026-06-17 01:53:23 +00:00
MartinYe1234andAnant Goel 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>
2026-06-16 22:50:58 +00:00
Danilo Leal 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.
2026-06-16 22:33:12 +00:00
João Soaresanddino 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>
2026-06-16 17:42:36 +00:00
Ben Kunkleandzed-zippy[bot] 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>
2026-06-16 17:29:30 +00:00
Ben Kunkle 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 ...
2026-06-16 17:29:10 +00:00
Cameron McloughlinandMartin Ye 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>
2026-06-16 17:04:21 +00:00
Ted RobertsonandSmit Barmase 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>
2026-06-16 16:17:06 +00:00
Lena b51bbef15b Ping on slack when a community-related workflow fails (#59435)
Release Notes:

- N/A
2026-06-16 16:09:57 +00:00
AAanddino 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>
2026-06-16 15:55:07 +00:00
Cameron BedardandSmit Barmase 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>
2026-06-16 15:46:37 +00:00
Richard Feldman 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.
2026-06-16 15:36:59 +00:00
Lena 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
2026-06-16 15:17:51 +00:00
Cameron Mcloughlin 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 ...
2026-06-16 15:07:25 +00:00
Gaauwe Rombouts 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
2026-06-16 14:59:26 +00:00
MartinYe1234 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
2026-06-16 14:31:33 +00:00