Commit Graph
38491 Commits
Author SHA1 Message Date
dino 5f9fa87928 chore: paint horizontal scrollbars on split buffer headers element
Update `SplitBufferHeadersElement::paint` in order to paint both left
and right editor's horizontal scrollbars after the buffer headers have
been painted.

The `ContentMask` applied to the buffer header has also been updated to
not actually mask if the horizontal scrollbar is above it, this ensures
we get a see-through effect on the horizontal scrollbar, just like we
have on the vertical one.
2026-06-16 13:01:29 +01:00
dino 02f80558e7 refactor: update horizontall scrollbar suppression logic
Since we actually already have `EditorElement::split_side`, we can
already determine, during prepaint, whether this is a split editor or
not. As such, this commit removes
`Editor::suppress_horizontal_scrollbar_paint` as well as its, as we no
simpy rely on `EditorElement::split_side` in order to understand whether
`EditorElement` should avoid painting the scrollbars altogether.
2026-06-16 12:44:47 +01:00
dino 562efb9405 chore: suppress painting of horizontal scrollbars on split editor
Update the split editor prepaint logic in order to suppress the
horizontal scrollbars from being painted by the editor element. These
will later be painted by `SplitBufferHeadersElement` when dealing with a
split editor, to ensure that we can paint them only after the buffer
header has also been painted, in order to ensure that we're able to
support translucent scrollbars, like we do for the vertical scrollbar.
2026-06-16 12:32:52 +01:00
dino b0c4f851bb chore: keep track of last horizontal scrollbar layout
* Introduce `Editor::last_horizontal_scrollbar_layout` so we can keep
  track of it after prepaint, as we'll need to know whether there's a
  horizontal scrollbar to paint or not.
* Introduce `Editor::suppress_horizontal_scrollbar_paint`, which will
  later be wired up in order to prevent `EditorElement` from painting
  the horizontal scrollbars.
2026-06-15 23:48:24 +01:00
dino c779aefa83 refactor: extract scrollbar layout's paint methods
Extract both `ScrollbarLayout::paint_thumb` and
`ScrollbarLayout::paint_track` so we can better control when these two
elements of the scrollbar are painted.

Having control over when these are painted will eventually allow us to
move this reponsibility to other places, when necessary.
2026-06-15 23:18:35 +01:00
Tom HouléandGitHub 9622ae92e1 agent_ui: Fix reporting of 401/403 errors (#59119)
When a Zed Business organization hits its token spend limit, the agent
panel told the user to "check that your API key has access to this
model", and did not display the error message returned by the server.
The message about checking your API key was the generic 401 and 403
error for all language model providers. This is also incorrect in
general since there are no API keys involved in the Zed and ChatGPT
Subscription providers.

So this commit changes the message for authentication errors (401s) to
be provider-specific, with the current message about invalid API key as
the default, and overrides for the providers that don't use API keys.
And the authorization error messages (403s) now include the server error
message. So the spend-limit case now reads "Permission Denied —
Token-based spending limit reached." instead of talking about API keys.

<img width="1888" height="426" alt="grafik"
src="https://github.com/user-attachments/assets/cf9e07cd-66f0-4f8d-828c-79b875edcf2d"
/>


Telemetry event names (`invalid_api_key`, `no_api_key`) are kept
unchanged to avoid breaking existing dashboards.

Release Notes:

- Fixed agent panel errors telling users to check their API key when the
provider doesn't use one (Zed account, ChatGPT subscription). Permission
errors also now show the provider's actual message.
2026-06-15 15:11:53 +00:00
DinoandGitHub e017293aed settings: Fix command aliases json schema (#57812)
The work introduced in https://github.com/zed-industries/zed/pull/54496
updated the `command_aliases` schema, adding support for auto-completion
action names when editing the settings file. However, it didn't take
into consideration the case where the user is simply creating an alias
to an arbitrary string.

These changes introduce a new `CommandAliasTarget` newtype for which the
json schema is either a registered action name, from `ActionName` or any
arbitrary string, as those are supported by the `command_aliases`
setting.

Updating the `ActionName` schema to accept any arbitrary string would
break the guarantees we have on the keymap binding schema, so that's why
a new schema was introduced.

Lastly, trying to set `CommandAliasTarget::json_schema` to a simply
`anyOf` with either the registered action name or a string that is not a
registered action name, like shown below, broke deprecation warnings,
hence why we're still doing the approach of only building
`CommandAliasTarget` at runtime.

```json
{
    "anyOf": [
        { "$ref": "#/$defs/ActionName" },
        { "type": "string", "not": {
            "$ref": "#/$defs/ActionName"
        }},
    ]
}
```

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed validation of `command_aliases` setting to avoid showing
warnings when aliasing to an arbitrary string
2026-06-15 14:22:47 +00:00
5e32405669 extensions_ui: Add RebuildDevExtension action (#55173)
For the extension devs:

Adds a `RebuildDevExtension` action that triggers a rebuild of an
installed dev extension.

- If no dev extensions are installed, shows an error notification.
- If exactly one dev extension is installed, rebuilds it immediately.
- If multiple dev extensions are installed, opens a fuzzy picker to
select which one to rebuild.

Makes it easy for devs to trigger a rebuild with a keymap once an action
is defined with this PR.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Closes #ISSUE

Release Notes:

- Added `RebuildDevExtension` action to rebuild installed dev extensions
from the command palette

<img width="675" height="310" alt="Screenshot 2026-04-29 at 1 49 54 AM"
src="https://github.com/user-attachments/assets/dbf618f7-f590-40aa-bc5c-580eea9f0001"
/>

<img width="623" height="329" alt="Screenshot 2026-04-29 at 1 50 16 AM"
src="https://github.com/user-attachments/assets/b4bb4131-924f-442b-8351-528a87698399"
/>

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-06-15 11:26:28 +00:00
6e129aa5df editor: Show file icon in breadcrumbs when tab bar is hidden (#56267)
[Screencast_20260509_113456.webm](https://github.com/user-attachments/assets/8165246f-6266-4e23-bede-0755e8636a19)

Release Notes: 

- Added file icons to the breadcrumbs when the tab bar is hidden

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-15 11:06:16 +00:00
saberoueslatiandGitHub 8a720e6c52 Anchor sticky scroll to symbol name rows (#56333)
## Context

Sticky scroll was anchoring multiline signatures to the first outline
context row instead of the row containing the symbol name, which could
leave the sticky header showing unhelpful context. This change carries
each outline item’s `selection_range` through the tree-sitter, LSP,
multi-buffer, and editor paths, then uses that range to choose the
sticky header row.

This is intended to improve sticky scroll generically, not only for one
language. It should help wherever symbol data distinguishes the symbol
name from the larger symbol range:
- tree-sitter outlines that provide a distinct `@name` capture
- LSP document symbols whose `selectionRange` is more precise than
`range`

The actual improvement is still language-dependent, because it relies on
the quality of each language’s outline query or language server symbol
metadata.

Closes #55587

Manual video of the test :

[Screencast from 2026-05-10
14-05-46.webm](https://github.com/user-attachments/assets/40f327d3-cab2-4b85-887b-08b541a102bf)


## How to Review

`crates/language/src/outline.rs`, `crates/language/src/buffer.rs`, and
`crates/language/src/buffer_tests.rs`: Adds `selection_range` to
tree-sitter outline items and verifies that multiline signatures can
anchor sticky scroll on the symbol-name row while preserving the
existing displayed outline text.

`crates/project/src/lsp_store/document_symbols.rs`: Threads LSP document
symbol `selection_range` into `OutlineItem`, keeping enriched labels and
highlight ranges intact while preserving the distinction between the
full symbol range and the selected name range.

`crates/multi_buffer/src/multi_buffer.rs`,
`crates/editor/src/document_symbols.rs`, `crates/editor/src/editor.rs`,
`crates/outline/src/outline.rs`, and
`crates/outline_panel/src/outline_panel.rs`: Propagates
`selection_range` through the places that remap outline items between
buffers, multi-buffers, editors, and outline views.

`crates/editor/src/element.rs` and `crates/editor/src/editor_tests.rs`:
Uses `selection_range` when computing sticky header rows and adds a
regression test covering a multiline signature case from the issue.

`crates/language/Cargo.toml` and `Cargo.lock`: Adds `tree-sitter-c` for
the language-level regression test fixture.

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed sticky scroll anchoring to unhelpful context rows for multiline
signatures when symbol metadata provides a more precise name range.
2026-06-15 11:03:26 +00:00
Miguel Raz Guzmán MacedoGitHubzed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>Smit Barmase
c642b422de util: Use job objects to reap spawned process trees on Windows (#58885)
On Windows, `util::process::Child::kill()` only terminated the direct
child process, and nothing tied the lifetime of spawned process trees to
Zed. External agent servers launched through ACP (e.g. `claude-code-acp`
via `npx`) spawn node workers and MCP servers as grandchildren, which
were orphaned on every session teardown and accumulated indefinitely —
hundreds of idle `node.exe` processes and GBs of RAM over days.

This PR assigns spawned processes to a Win32 job object configured with
`JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE`:

- `kill()` now calls `TerminateJobObject`, killing the entire tree
instead of just the (shell wrapper) child.
- Dropping `Child` closes the job handle, which makes the OS reap the
tree — including when Zed exits for any reason (even crashes), since the
OS closes its handles.
- Unix behavior (process groups via `killpg`) is unchanged.

Added two Windows tests that spawn a real `powershell -> ping` process
tree and assert the grandchild is terminated on `kill()` and on drop.
Both fail without the fix and pass with it. Verified with `cargo test -p
util`, `script/clippy -p util`, and `cargo check -p agent_servers -p
dap` on Windows 11.

Closes #58873

Release Notes:

- Fixed external agent servers and debug adapters leaking helper
processes (e.g. node workers and MCP servers) on Windows.

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-06-15 10:55:39 +00:00
Danilo LealandGitHub d8eb569cc5 acp_thread: Fix compaction button stuck at loading state on error (#59161)
Closes AI-393

When the user proactively cancels a turn, we mark all pending entries as
cancelled. But if something else stops/halts a turn, we weren't doing
that in the case of compaction, which means we would be stuck in a
loading state forever.

Release Notes:

- N/A _(feature hasn't been publicly released yet so no notes)_
2026-06-15 10:54:31 +00:00
7726682898 git: Optimize git HEAD state resolution (#59044)
Currently zed runs `git rev-parse HEAD` and `git show` sequentially to
get the git `HEAD` state in `compute_snapshot`.

`git show` already natively resolves the `HEAD` commit so we can
retrieve all info in a single process spawn which speeds things up and
removes one git background process.

Followup on #59042 in the hope to improve performance of working with
large git repos over SSH.

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 performance of git HEAD state resolution

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-06-15 10:05:36 +00:00
Lukas GeigerandGitHub 5e514f4624 git: Reduce amount of git commands when checking for pushed commits (#59069)
When uncommiting we check whether the commit already exists on a remote
branch. This currently spawns a lot of git processes to do so,
especially when having multiple remotes.

This PR switches this to a single `git for-each-ref` call to do the same
checks. I tested this in the UI and added some unit tests to verify this
behaviour.

This is a followup on #59053, #59044 and #59042 with the goal to reduce
overhead of the git handling.

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 performance of git uncommit
2026-06-15 09:29:41 +00:00
CollinandGitHub ae7717dbe0 Edit name of Gemini 3.1 Flash Lite to Gemini 3.1 Flash-Lite to better match Google's official documentation (#59322)
## Solution

- A simple find and replace.

## Testing

- Did you test these changes? If so, how? No, as in my opinion, a single
character change in a string does not justify the time it takes to
recompile
- Are there any parts that need more testing? No.
- How can other people (reviewers) test your changes? Is there anything
specific they need to know? Just open the models UI.
- 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

---

Release Notes:

- Edit name of Gemini 3.1 Flash Lite to Gemini 3.1 Flash-Lite to better
match Google's official documentation
2026-06-15 09:17:46 +00:00
338530f2e9 Fix ghost project when selecting remote project group (#59272)
# Objective

Fixes #54882:

When selecting a project group that has a remote host (SSH, WSL, Docker)
from the window project picker, or when closing/removing a workspace
with a remote neighbor group, the code was unconditionally calling
find_or_create_local_workspace. This created a local project with the
remote server's paths, producing a 'ghost' project where language
servers and file watchers fail trying to access paths that don't exist
locally.

## Solution

Three locations fixed:

1. RecentProjectsDelegate::confirm (recent_projects.rs) - window project
picker selecting a ProjectGroup entry. Routes to
find_or_create_workspace with connect_with_modal for remote hosts.

2. MultiWorkspace::close_workspace (multi_workspace.rs) - closing a
workspace whose neighboring group is remote. Falls through to the empty
workspace fallback instead of creating a ghost project.

3. MultiWorkspace::remove_project_group (multi_workspace.rs) - removing
a project group whose neighbor is remote. Same fallback.

All three detect remoteness via key.host().is_some() and skip
find_or_create_local_workspace when set.

Includes regression tests for all three paths using mock remote
connections.

## Testing

- Not yet tested with a custom build
- Unit tests added

## 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

---

Release Notes:

- Fixed ghost project appearing in the window project picker and sidebar
when switching between local and remote projects.

---------

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
2026-06-15 09:02:10 +00:00
Kunall BanerjeeandGitHub b2143f449b recent_projects: Show keybindings in action button tooltips (#59030)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Closes #59024.

Release Notes:

- Fixed missing keybinding hints in the Recent Projects picker action
button tooltips
2026-06-15 08:53:41 +00:00
DinoandGitHub 62b4fd26cf git_ui: Always display "Create Pull Request" button on push toast (#53913)
Update the toast shown after running `git: push` so as to always include
a button to create a pull request for the current branch.

We used to only do this on the initial push, as that is when the output
of running `git push` would include an URL that could be used to create
the Pull Request. However, since we now have a `git: create pull
request`, we can always build this URL, meaning we no longer need to
rely on the command's output in order to display the "Create Pull
Request" button.

Something worth noting is that the
`git_ui::remote_output::format_output` function used to also match on
Bitbucket's terminal output, so these changes include the implementation
of `GitHostingProvider::build_create_pull_request_url` for the
`Bitbucket` provider.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Improved the toast shown after `git: push` to always display the
"Create Pull Request" button
2026-06-15 08:48:19 +00:00
18c98b0211 Fix incorrect mask in BufferChunks::next (#57544)
I noticed while working on a personal project which derives some logic
from the core Zed stack that I was getting very unexpected results out
of BufferChunks::next when walking through formatted chunks.

The code calculates the mask for the `tabs`, `chars`, and `newlines`
masks incorrectly, making the mask far too large when we are extracting
chunks when chunk_start != 0.

I believe the reason that this isn't a problem in Zed is that the
InlayMap ends up re-masks all the bitmasks before passing things up the
stack, so covers up the problem, preventing it from causing any damage.
It appears this isn't caught in tests because this only happens when
extracting chunks with formatting, during which we offset our retrieval
by next_capture_start, and the current chunks tests don't use
formatting.

I think the fix is sound. The test is maybe not super ideal, but I
wanted to demonstrate the issue in the pull request.

If we process the following text by chunks:
```rust
use std::cmp::Eq;
```

The first chunk is 'use ' with the chars mask being 0b1111. The second
chunk is 'std' with the chars mask being 0b1111111 when it should just
be 0b111.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:
 - N/A

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-06-15 08:23:15 +00:00
838fea165c docs: document llvm-objcopy --strip-debug step when self-building remote_server (#57655)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments (N/A — docs only)
- [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 (N/A — docs only)
- [x] Performance impact has been considered and is acceptable

Documents the `llvm-objcopy --strip-debug` step that
`script/bundle-linux` runs after `cargo build`. Without it, self-built
`remote_server` binaries are ~462 MB instead of ~62 MB and behave
differently from the prebuilt downloads.

Two contributors converged on the same fix in the issue thread; this PR
is a docs-only version of their suggestion, plus the musl/static variant
that `script/bundle-linux` actually uses for the official Linux release.

Closes #56939

Release Notes:

- N/A

AI was used for assistance.

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-06-15 08:17:56 +00:00
Smit BarmaseandGitHub 6d0e7ff18c editor: Fix blocks not appearing or lingering when anchored past a soft wrap (#59018)
I came across this while tackling another block map sync issue.

When a block is anchored past the point where its line soft wraps,
inserting or removing it invalidated the wrong range of rows. Inserting
such a block alone could silently not show it, and removing it could
leave the block on screen.

To reproduce: 

```sh
SEED=113 ITERATIONS=1 cargo test -p editor test_random_blocks
```

Release Notes:

- Fixed inline assistant prompt sometimes not appearing, or lingering
after dismissal, when that line was soft-wrapped.
2026-06-15 07:56:52 +00:00
71fe7ec366 agent_ui: Insert dropped file links at the cursor (#55127)
## Context

Dragging a file from the Project Panel into the agent composer was
appending the generated file mention to the end of the prompt instead of
inserting it at the active caret position. This change routes dragged
file insertion through the same caret-based mention insertion path
already used for pasted external paths, so dropped file and directory
mentions are inserted inline where the user is typing.

Closes #55002

Video of the manual test below :

[Screencast from 2026-04-29
01-13-59.webm](https://github.com/user-attachments/assets/9d2196fb-accd-4f4a-a9c0-0ce45b212121)

## How to Review

-
[crates/agent_ui/src/message_editor.rs](/home/saber/coding/zed/crates/agent_ui/src/message_editor.rs)
removes the separate end-of-buffer insertion mode from
`insert_mention_for_project_path`, updates `insert_dragged_files` to use
the shared caret-based insertion flow, and adds regression tests
covering single-file and multi-file drag insertion order at the cursor.
The existing paste-at-cursor behavior remains covered by the
pre-existing test in the same module.

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the UI/UX checklist
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed dragged file mentions in the agent composer being appended to
the end of the prompt instead of inserted at the cursor

Co-authored-by: Richard Feldman <richard@zed.dev>
2026-06-15 07:56:37 +00:00
Lukas GeigerandGitHub 346d3605cf git: Reduce number of spawned git processes when retrieving default branch (#59087)
Retrieving the default branch currently spawns up to 5 git processes
sequentially which isn't ideal.
This PR switches to a `git for-each-ref` and `git config` call to do the
same checks while requiring spawning less git processes. I tested this
in the UI and added a unit test to verify that the behaviour doesn't
change.

This PR follows the approach from #59069.

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 performance of retrieving default git branch
2026-06-15 07:44:28 +00:00
Lukas GeigerandGitHub e770c94187 git: Reduce number of spawned git processes when retrieving remote URLs (#59053)
Currently Zed fetches remote URLs by sequentially calling `git remote
get-url origin` and `git remote get-url upstream`.
This PR introduces a new `remote_urls` function which uses `git remote
-v` to retrieve all remote fetch URLs with a single git process.

Followup on #59042 and #59042 in the hope to reduce the amount of
spawned git processes.

Probably best to review both commits separately.

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 performance of listing git remotes
2026-06-15 07:26:48 +00:00
Lukas GeigerandGitHub a31d3505da git: Do not run git stash list on every file save (#59042)
Currently `git stash list` will run on every `paths_changed` event e.g.
every time files are modified or saved.
This is unnecessary since the git stashes will only change when a `git
stash` command is run. Which can either happen from within Zed or from a
terminal. Changes there are already tracked by monitoring
`.git/logs/refs/stash`.
I verified that Zed's git stash view still works as expected.

I'm noticing that Zed performs very badly when working with a large git
repo via SSH remote development. In particular I've noticed bad
performance when working with https://github.com/pytorch/pytorch which
includes lots of submodules.
I'm hoping that this PR will reduce the amount of git processes and
hopefully make it more responsive without having to manually add folders
to `file_scan_exclusions`.

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:

- Reduce git processes run on every file change
2026-06-15 07:12:57 +00:00
Toru NayukiandGitHub 26fc42721a dev_container: Support the classic Docker builder via a setting (#59288)
Dev container image builds default to BuildKit (`docker buildx`).
Docker-compatible engines that lack an integrated BuildKit — notably
[Apple Container](https://github.com/apple/container) accessed through a
Docker-API bridge — cannot resolve a locally-built image in a `FROM`,
which breaks the dev container build: Zed builds the features image,
then a second `FROM <features-image>` build (the UID remap), and
BuildKit's docker-container/remote drivers can't see the daemon's local
image, failing with `pull access denied`.

The daemon's *classic* builder resolves locally-built images, and Zed
already generates a BuildKit-free Dockerfile for the non-BuildKit path
(multi-stage `FROM` + `COPY --from`, no `RUN --mount`). This wires that
path to a setting and makes the remaining build invocations actually use
the classic builder.

## Changes

- Add a `dev_container_use_buildkit` setting (tri-state):
- unset → auto-detect via the `docker buildx` plugin (current behavior)
  - `false` → force the classic builder
  - `true` → force BuildKit
- When the classic builder is selected, pass `DOCKER_BUILDKIT=0` (and
`COMPOSE_DOCKER_CLI_BUILD=0` for compose) to the feature-content build,
the compose build, and the UID-remap build, so multi-stage `FROM` of a
locally-built image resolves through the daemon's classic builder.
- Document the setting in `docs/src/dev-containers.md`.

With this setting plus a Docker-API bridge, a real Rails dev container
(compose: app + mysql + valkey, with features) builds and starts on
Apple Container.

## How to Review

- `settings_content.rs` / `dev_container/src/lib.rs` — the new setting
and its plumbing into `DevContainerContext`.
- `docker.rs` — `Docker::new` honors the setting
(`supports_compose_buildkit`), `docker_compose_build` selects the
classic builder; unit test
`use_buildkit_setting_overrides_buildx_detection`.
- `devcontainer_manifest.rs` — `DOCKER_BUILDKIT=0` for the
feature-content and UID-remap builds.

## Self-Review Checklist

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Added a `dev_container_use_buildkit` setting to build dev containers
with the classic Docker builder for engines without an integrated
BuildKit (e.g. Apple Container)
2026-06-15 07:04:03 +00:00
procr1337andGitHub c578f4d12b agent: Fix shell hang on shell syntax errors with terminal tool usage (#59270)
# Objective

When the agent's terminal tool runs a command with an unsupported shell
syntax (e.g. process substitution `<()` in dash), the shell prints an
error and then drops into interactive mode. It shows a `$` prompt and
hangs waiting for input, requiring the user to press Ctrl+D to continue.

This happens because the stdin redirect wraps the command in a subshell
`(...) </dev/null`, which only closes stdin for the inner command. The
outer shell still has its stdin connected to the PTY, so after a syntax
error it reads from the PTY and waits for more input.

## Solution

Replace the subshell wrapping with an `exec`-level redirect. Instead of:

```sh
sh -i -c '(command\n) </dev/null'
```

We now produce:

```sh
sh -i -c 'exec </dev/null; command'
```

`exec </dev/null;` closes stdin for the **entire shell process**. If the
command fails with a syntax error, the shell immediately gets EOF from
stdin and exits cleanly instead of prompting for more input.

The `-i` flag is preserved so that shells which support it still source
their interactive init files and enable job control.

This change applies to `ShellKind::Posix` (sh/bash/dash/zsh) and
`ShellKind::Fish` in both `ShellBuilder::build()` and
`ShellBuilder::build_no_quote()`.

## Testing

- Manually verified that `cat <(echo hi)` (process substitution in dash)
no longer hangs: the shell exits immediately with the syntax error

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed agent terminal tool hanging with a `$` prompt when commands
encounter syntax errors or unsupported shell features like process
substitution
2026-06-15 07:03:24 +00:00
Toru NayukiandGitHub 832ab56db8 dev_container: Expand bare $VAR in addition to ${VAR} in Dockerfiles (#59280)
When expanding build args in a dev container Dockerfile, only the braced
`${VAR}` form was substituted. The bare `$VAR` form — which is valid
Docker
syntax and common in real-world Dockerfiles — was passed through
verbatim.

For example, the Rails dev container images use:

```dockerfile
ARG RUBY_VERSION=3.4.4
FROM ghcr.io/rails/devcontainer/images/ruby:$RUBY_VERSION
```

This left `$RUBY_VERSION` unexpanded, so the subsequent `docker inspect`
/
build ran against the literal string `ruby:$RUBY_VERSION` and failed
with
an invalid reference format.

This adds `expand_dockerfile_var`, which substitutes both `${VAR}` and
bare
`$VAR`. Bare `$KEY` is only replaced when it is not immediately followed
by
a word character, so expanding `$RUBY_VERSION` does not partially
consume
`$RUBY_VERSION2`.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed dev container Dockerfiles not expanding build args written in
the bare `$VAR` form

Signed-off-by: Toru Nayuki <tnayuki@icloud.com>
2026-06-15 06:54:17 +00:00
Xin ZhaoandGitHub cccc7b2d44 editor: Fix splitting brackets inside line comments (#59260)
# Objective

Closes #59229

When adding a newline, Zed has a bit of intelligence to do more work
than just inserting a `\n`. For comment lines, it simply extends the
comment:
```rust
Before
// This is a comment, ˇThis is another comment


After
// This is a comment, 
// ˇThis is another comment
```
And when the cursor is inside bracket pairs, Zed inserts another newline
to move the closing bracket to a new line:
```rust
Before
fn main() {ˇ}


After
fn main() {
    ˇ
}
```
However, when we have a comment line with the cursor inside a bracket
pair, both mechanisms apply, resulting in an unintended state where the
closing bracket is kicked out of the comment:
```rust
Before
// {ˇ}

After
// {
// ˇ
}
```

We definitely do not need the bracket extension rule when we are adding
a newline inside comments. We want comment lines inside brackets to be
split like this:
```rust
// {
// ˇ}
```

## Solution

- Disable Bracket Extra Newline in Comments: When a line comment
delimiter is detected, we override the default `newline_config` to set
`extra_line_additional_indent` to `None` .
- Avoid Rule Conflicts (Short-circuiting): The three newline
customization helpers (line comment, block comment, and list item) are
mutually exclusive. I refactored their execution from a sequential list
into an `if let Some ... else if let Some` branch. This prevents
subsequent rules from having side effects on `newline_config` when a
match has already occurred.

## Testing

A new test named `test_newline_comments_with_brackets` is introduced in
`crates/editor/src/editor_tests.rs`, All tests in the `editor` crate
were verified using `cargo test -p editor` .

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

---

Release Notes:

- Fixed an issue where splitting brackets inside line comments inserted
an extra line and broke the comment formatting
2026-06-15 03:54:00 +00:00
Sergei G.andGitHub 759bacff37 gpui_macos: Warn when falling back to NoopTextSystem (#59247)
# Objective

Without the `font-kit` feature, `MacPlatform` silently substitutes
`gpui::NoopTextSystem`, which accepts fonts and resolves font ids but
rasterizes every glyph to an empty bitmap.

I hit this with the `component_preview` example
https://github.com/zed-industries/zed/pull/59241.

## Solution

Log a warning at startup in `MacPlatform::new()` when falling back to
`NoopTextSystem`. Skipped in headless mode, where no text is expected to
render and the fallback is a reasonable configuration.

## Testing

Checked as part of https://github.com/zed-industries/zed/pull/59241

## 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)

## Showcase

It just render as like without any error:
<img width="1312" height="945" alt="cp_pr1_before"
src="https://github.com/user-attachments/assets/f5faf3c0-9523-4c5f-9756-e65cbaf3456f"
/>


---

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-06-15 03:49:04 +00:00
Danilo LealandGitHub cb7721602b file_finder: Adjust list item design (#59164)
Follow up to https://github.com/zed-industries/zed/pull/59072 adjusting
some UI design for the file finder that got regressed.

Release Notes:

- N/A
2026-06-15 03:31:50 +00:00
Sergei G.andGitHub f9d57b54dc component_preview: Fix example rendering no text or icons (#59241)
`cargo run -p component_preview --example component_preview` does not
work.
On current main it panics at startup:

```
thread 'main' panicked at crates/gpui/src/action.rs:296:13:
Action with name `zed::Quit` already registered
```

With that panic fixed, the window opens but renders no text and no icons
(see Showcase below).s

## Solution

Root cause for the blank window: `component_preview` package resolves
`gpui_platform` with just `"screen-capture"`.

On macOS the missing `font-kit` feature makes `MacPlatform` fall back to
`gpui::NoopTextSystem`, as mentiond also in README (or CONTRIBUTE) file.

On Linux the missing `wayland`/`x11` features leave no windowing backend
at all.

list of changes:

- Enable the same `gpui_platform` features as the `zed` binary.
- Attach `Assets` and load the embedded fonts.
- Initialize `env_logger` so platform warnings reach the terminal.
- Fix three startup panics: move the example's `Quit` action to the
`component_preview` namespace.

## Testing

Tested on macOS/Linux, not tested on Windows. I use Parallel VMs.

## 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)

## Showcase

Before:
<img width="1312" height="945" alt="cp_pr1_before"
src="https://github.com/user-attachments/assets/4611596f-6775-4863-bd4a-5f4d8c642e35"
/>

After:
<img width="1312" height="945" alt="cp_pr1_after"
src="https://github.com/user-attachments/assets/8f8082e6-c8cd-48f5-946a-032ce8186d30"
/>

---

Release Notes:

- N/A
2026-06-15 03:26:51 +00:00
Finn EversandGitHub f39cf25c0b extension_ui: Hide agent servers from chips (#59231)
This fixes an issue where we would still allow users to toggle for agent
servers but would not actually show them any results, since they are all
suppressed.

Also slightly changes the order in which we present the provides chips:
Languages is now first, and debug adapters are now further up.

Release Notes:

- Removed the agent server chip from the extension UI search filder.
2026-06-14 16:42:12 +00:00
Danilo LealandGitHub 29b90dc4e8 markdown_preview: Improve heading spacing (#59291)
Follow up to https://github.com/zed-industries/zed/pull/58465 adding
more breathing room between headings _and_ making inline code links use
the `accent` text color.

Release Notes:

- N/A
2026-06-14 12:11:15 +00:00
c7987fabf7 agent_ui: Truncate long model names in config option selector (#57808)
Long model identifiers (e.g., AWS Bedrock ARNs) overflow the bottom
toolbar, breaking the layout. Truncate display names to 32 characters
with an ellipsis when they exceed 33 characters.

### Before

<img width="1128" height="308" alt="after"
src="https://github.com/user-attachments/assets/000d5959-3bd5-4349-8f4e-09967ea7b2d8"
/>

### After

<img width="1010" height="212" alt="before"
src="https://github.com/user-attachments/assets/358fff8c-3bce-43ac-aed4-8ef630fc327b"
/>

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](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

Release Notes:

- Agent: Improved truncation of long configuration button labels for
external agents.

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
2026-06-14 11:28:27 +00:00
df9c9f055e agent_ui: Match project name in archive-view search (#58214)
Summary:

When you have a lot of projects open, finding a thread from a specific
project in the archive ("Search all threads") view is slower than it
should be — the filter only matches the thread title, so you have to
remember or scan titles to find what belongs to which project. Folder
names are a quicker mental handle than thread titles, especially across
many projects.

This PR makes the archive filter also try matching the basename of each
of the thread's worktree paths. Title matches still take precedence and
get the highlight positions; project-name matches just include the row.
Same `fuzzy_match_positions` contiguous substring matcher already used
for titles, so the matching feel is consistent.

Example: typing `my-laravel-project` now surfaces every thread that
lives
under a project named `my-laravel-project`, regardless of title.

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
- [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 — small extension to an
existing filter branch; manually verified.
- [x] Performance impact has been considered and is acceptable — per-row
path-basename check only runs when the title didn't match.

Release Notes:

- Improved the archive "Search all threads" view so you can filter by
project name, not just by thread title — handy when many projects are
open.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-06-13 16:39:16 +00:00
Matei OpreaandGitHub e044074eb2 recent_projects: Close remote projects window on button press (#58889)
When clicking the "Open Folder" button in a remote project window, the
"Remote Projects" window was not being dismissed. Now we're emitting a
DismissEvent so we can close it.

Release Notes:

- Fixed the Remote Projects modal not being dismissed on "Open Folder"
click.
2026-06-13 15:45:33 +00:00
Finn EversandGitHub 3e54ce8bce client: Link to appropriate documentation for Preview and Nightly (#59234)
This will make users benefit more from the recent staged docs releases.

Release Notes:

- N/A
2026-06-13 13:16:01 +00:00
Finn EversandGitHub 1e017d04b9 agent_ui: Remove dead link in agent menu (#59232)
The link 404s for me on all channels, thus removing it and the context
menu entry here.

Release Notes:

- Removed a dead link in the agent menu.
2026-06-13 13:00:44 +00:00
Matt HarrisonandGitHub 8589cbbf6b Allow Prettier to read the .editorconfig files of the project when formatting from within Zed (#59149)
allow Prettier to read the .editorconfig files of the project when
formatting from within zed.

Prettier's API requires passing the `{ editorconfig: true }` option to
read .editorconfig files. The prettier CLI uses this option by default
when running but the API does not.

API Option for this:
https://prettier.io/docs/api#prettierresolveconfigfileurlorpath--options

Code where the CLI of prettier defaults this to true to show this option
aligns with Prettier's defaults.

-
https://github.com/prettier/prettier/blob/7e374c3cd024b2bd1b5d88e005aec3718b60f1b6/src/cli/cli-options.evaluate.js#L162
-
https://github.com/prettier/prettier/blob/7e374c3cd024b2bd1b5d88e005aec3718b60f1b6/src/cli/options/get-options-for-file.js#L72

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
  - No tests were found that covered running prettier directly.
- [x] Performance impact has been considered and is acceptable

Closes #10828

Release Notes:

- Allow Prettier to read the .editorconfig files of the project when
formatting from within zed.
2026-06-13 05:21:05 +00:00
Cole MillerandGitHub fca2ccd403 Revert "gpui: Fix title bar clicks being delayed on macOS 27 (#58947)" (#59214)
This reverts commit c8554b46e7.

Reverting this because it broke dragging the settings UI window.

Closes https://github.com/zed-industries/zed/issues/59163

Release Notes:

- Fixed not being able to drag the settings UI window on macOS.
2026-06-12 19:36:52 +00:00
abbe85a332 call: Log LiveKit connection info refresh outcomes in retry loop (#59205)
Follow-up to #59195. While verifying that fix against prod we hit a log
that couldn't distinguish "retrying with a fresh token that is still
revoked" from "silently retrying with the same dead token because the
server returned no connection info" (e.g. a collab deploy predating
#59195). Make the retry loop self-diagnosing:

- Warn when `RejoinRoomResponse` carries no `live_kit_connection_info`,
since the loop then reuses the existing token.
- On refresh, log whether the token actually changed.

Release Notes:

- N/A

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:48:42 +00:00
96285fc140 editor: Align split buffer headers with scrollbar layout (#53782)
Clip split buffer headers to the editor's content bounds so they no
longer paint into the horizontal scrollbar area.

Reuse the editor's computed right margin and horizontal scrollbar
visibility instead of reimplementing scrollbar detection in
split_editor_view. This keeps split headers aligned when minimap, inline
blame, or scrollbar visibility change the available content area.

Release Notes:

- Fixed horizontal scrollbars not being rendered behind buffer headers
in split editors

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-06-12 15:37:55 +00:00
MartinYe1234andGitHub 26a355b11d repl: Show kernel error on notebook cell instead of hanging (#59137)
Closes AI-394

When the kernel isn't running — e.g. Python isn't installed, ipykernel
is missing, or the kernel failed to launch — clicking run on a notebook
cell would unconditionally enter the executing state and silently drop
the execute request. The cell then spun forever with no logs and no way
to cancel (the stop button only works on a running kernel).

This change makes `execute_cell` attempt to send the execute request
first, and only mark the cell as executing when the send succeeds. On
failure it:

- Renders the failure (including the original kernel launch error) as an
error output on the cell, reusing the same `ErrorView` used for Python
tracebacks
- Logs the reason at the moment run is clicked, instead of only once at
notebook open
- No longer swallows `try_send` errors when the kernel process has died

Also adds the first unit test for the notebook editor, which exercises
the production path end to end: a real `.ipynb` parsed via
`NotebookItem::try_open`, a kernelspec pointing at a nonexistent
interpreter selected through `ReplStore::set_active_kernelspec`, a real
failed process spawn, and assertions through the production save path
(`to_nbformat_cell`). Verified red/green: the test fails against the
previous behavior.

Note for future notebook tests: `NotebookEditor` renders a continuously
animating kernel status icon, so rendering it as a root view in a GPUI
test makes `run_until_parked` spin forever. The test creates the editor
inside an empty window instead.

Release Notes:

- N/A
2026-06-12 14:57:52 +00:00
d4cc8d2409 Patch async-process to allow reusing their reaper (#59156)
See
https://github.com/zed-industries/async-process/commit/0b6d6713570af61806e1e5cb40e0f757cb93fd9d

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable

Release Notes:

- Fixed orphaned processes being leaked on macOS

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2026-06-12 14:38:03 +00:00
Piotr OsiewiczandGitHub 1d217ee39d ci: Fix caching of release jobs (by having it in the first place) (#59200)
# Objective

We were not caching builds for nightly/bundling jobs AT ALL.

## Solution


## Testing

## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable



Release Notes:

- N/A
2026-06-12 14:13:01 +00:00
138139f830 gpui_macos: Fix traffic light hitbox after repositioning (#58534)
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 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

Release Notes:

- N/A

This is a follow up to https://github.com/zed-industries/zed/pull/58169
and https://github.com/zed-industries/zed/pull/58518 after removing a
bunch of unsafe usage.

Before this, GPUI moved traffic lights by directly changing the native
button frames inside AppKit’s existing titlebar layout and the old
y-coordinate was based on the native titlebar height, so the buttons
moved visually while the titlebar tracking geometry could still be based
on the old layout.

Now the native titlebar container is resized and repositioned to contain
the traffic lights. We capture the original AppKit titlebar/button
frames, resize the titlebar container to fit the requested position,
move the native close/minimize/zoom buttons inside that container and
update AppKit tracking areas. This keeps the visible buttons and
hover/click geometry aligned.

### Before


https://github.com/user-attachments/assets/77dde6cb-3fc8-4166-bc86-22cf2c93e119

### After


https://github.com/user-attachments/assets/da84ade6-ef47-4e53-ae4a-3779315773f9

---------

Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
2026-06-12 14:08:25 +00:00
Piotr OsiewiczGitHubdinoDinozed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
e5b6041e9d audio: Fix phantom presence in channels (#59195)
# Objective

You know that feeling? You join the channel, crack a banger joke to
break the ice - yet, nobody laughs. Worse yet, you're swarmed with Slack
messages like "Piotr, we can't hear you". After a while you realize that
maybe it's for the best as the joke was not as good as you've initially
thought, but still: it's possible to get into a state where other
participants see you as muted. You don't hear anybody. Bummer.

That's what happened when we were hoping to pair with @dinocosta today.
I could not hear him. However, he had some logs to share which indicated
that while collab thought he's in the room with me, live-kit was
rejecting his token as it was revoked.

What clanker helped us figure out is that there's a race-y code path
where if you disconnect from a given room abruptly, collab can put you
in a limbo.
<details><summary>Clanker's idea of what's going on</summary>
<p>
Found the whole story. Here's what those logs mean and where the bug
surface is.

What's happening

The error at room.rs:1809 is the detach_and_log_err on the task spawned
by spawn_room_connection (crates/call/src/call_impl/room.rs:1754-1810).
So this is the initial livekit::Room::connect call failing — the LiveKit
SDK internally retried 3 times (that's the retrying... (1/3) lines), got
401 invalid token: revoked every time, gave up, and the error propagated
out of the ? at line 1762 and was logged-and-dropped.

The "revoked" comes from the collab server: leave_room_for_session
(crates/collab/src/rpc.rs:4091-4095) calls
live_kit.remove_participant(livekit_room,
session.user_id().to_string()), and LiveKit Cloud treats a removed
participant's token as revoked. Crucially, the LiveKit identity is just
the user id, not the connection id, while the DB-side
leave_room(connection_id) is per-connection. leave_room_for_session
fires from three places:

1. Explicit leave (rpc.rs:1666)
2. connection_lost, after RECONNECT_TIMEOUT expires (rpc.rs:1342)
3. Stale-connection cleanup when re-joining a channel (rpc.rs:3401)

So there's a race: an old connection's delayed cleanup (path 2) can fire
after the same user has rejoined the room on a new connection and been
issued a fresh token — and remove_participant(room, user_id)
kicks/revokes the user's current LiveKit participant, because the
identity is shared across connections. Quick restart of Zed, two
instances, or a reconnect that straddles the server's RECONNECT_TIMEOUT
all set this up.

Client-side consequences (this connects to your first question)

When that initial connect fails:

- this.live_kit stays None and this.diagnostics is never created — lines
1780-1791 only run on success. So in this failure mode CallDiagnostics
doesn't exist at all; the "stats never overridden" path I described
earlier isn't even reached.
- There is no retry and no token refresh. The failure is
detach_and_log_err'd and that's the end of it. The user stays in the
room at the collab level (status is still Online, they appear in the
channel), but with no audio and no way to recover short of leaving and
rejoining.
- Even a collab-level reconnect doesn't help: RejoinRoomResponse
(crates/proto/proto/call.proto:58) carries no live_kit_connection_info,
and rejoin() never calls spawn_room_connection — the LiveKit connection
is established exactly once, in Room::new, with the token from the
original join response.

So the user-visible symptom is: you're "in" the call, everyone sees you,
but you can't hear or be heard, and there's no error surfaced in the UI
— just this log line.

If you want to fix it, the two angles are server-side (make
leave_room_for_session skip the LiveKit removal when the user still has
a live connection in that room, or scope LiveKit identities
per-connection) and client-side (treat a failed spawn_room_connection as
fatal-but-recoverable: surface it, and have rejoin request fresh
connection info instead of silently carrying on). Happy to dig into
either if you want.


</p>
</details> 

So tl;dr: our token was swapped out underneath us. One way to "fix" it
was to just go into another channel, but that was a bummer.

We have a good and reliable repro for it though: `kill -9 $ZED_PID`
followed by an attempt to rejoin the same channel within 30s would
consistently put us in that state.
Put another way: you panic and thus do not send a clean "leave room"
message to LK. if you rejoin the channel within 30s (after restarting),
LK will invalidate the very token you're attempting to use (as it cleans
up old tokens).

It may also happen without crashing, but that's the most reliable way to
repro the issue. Long story short your LK token gets tainted and you
can't share the audio anyhow.

## Solution

The fix is both client and server-side.

On client's side, we now retry the reconnection with a back-off and we
grab a fresh token off of reconnect attempts.
On server's side, we share the current token on room reconnect attempts.

We've also tweaked the call diagnostics to not use `unwrap_or_default`
so much: it was hard for us to tell that we're in a totally bogus state
and we've only reached that conclusion based on source code analysis. We
now show some generic "ok you're in a borked state pls report a bug"
message instead.

## Testing

We added tests that present the flacky scenario. We've also tried to
setup an infra to test the new behaviour, but sadly, local LK instance
seems to revoke tokens more leniently than the prod..
OTOH, we are quite confident that once new collab is deployed, we'll be
able to mince the new tokens and life is going to be good. Even when
running against the current prod instance we could see that our code
changed the behaviour for the better, as now we'll actually try to use a
new token if one is provided by collab. For that to happen we need to
redeploy though.


## Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable


Release Notes:

- Fixed a race condition that caused collab users to not receive/send
any audio to their peers.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
Co-authored-by: Dino <dino@zed.dev>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-12 12:54:29 +00:00
Lukas WirthandGitHub b6c7496aea multi_buffer: Don't eagerly clone BufferSnapshot in range_to_buffer_ranges (#59190)
Both cloning and dropping of these has quite a bit of overhead (despite
them being snapshots), so avoid where possible, especially in display
map syncing

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-06-12 12:27:28 +00:00
992f395c3d editor: Fix columnar selection alignment on rows with multi-byte chars (#57097)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](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 #56748

## Summary

Block / column selection (Shift+Ctrl+drag on Linux, Shift+Cmd+drag on
macOS) anchored its rectangle on a single byte column applied to every
row in the dragged range. On a row whose text contained a multi-byte
character before that column (for example `ã`), the same byte offset
mapped to a different visual `x`, so the per-row cursor drifted off the
column.

`select_columns` now anchors the rectangle in `x` pixels via
`x_for_display_point` and resolves each row's byte column with
`display_column_for_x` — the same pair of helpers already used by
vertical cursor motion and Vim VisualBlock.

## Before / After

**Before** — cursor on the `ã` row drifts one column to the left:

<img width="1068" height="366" alt="image"
src="https://github.com/user-attachments/assets/0559ef89-852e-40f3-9d43-f5f44277f99e"
/>


**After** — rectangle stays visually aligned across rows:

<img width="866" height="408" alt="image"
src="https://github.com/user-attachments/assets/bce13c1a-1ddb-4fd6-8216-2c0e902f6668"
/>


## Test plan

- `cargo test -p editor test_columnar_selection_with_multibyte_chars`
(new regression test covers the buggy case past the `ã` byte boundary,
plus a control case where old and new logic agree).
- Manual: Shift+Ctrl+drag down a five-line buffer where row 3 contains
`ã` — selection rectangle stays aligned (see screenshots).
- Manual: Shift+Alt+drag (`FromSelection` branch) over the same buffer —
same result.
- Manual: drag past EOL on the `ã` row — each row extends to its own EOL
with no panic.

Release Notes:

- Fixed misalignment of column selection on rows that contain multi-byte
characters

---------

Co-authored-by: Tom Houlé <tom@tomhoule.com>
2026-06-12 09:54:50 +00:00