100 Commits
Author SHA1 Message Date
Jakub Konka a34b723967 gpui_web: Disable native canvas selection (#63877)
Follow up on #63775: disabling WebKit touch callouts did not fully
prevent iOS Safari from selecting the entire GPUI canvas alongside the
app's text selection.

Remote Web Inspector captured a viewport-sized DOM range containing the
canvas while its computed `-webkit-touch-callout` was `none` but
`-webkit-user-select` was `text`. Set both standard and WebKit-prefixed
`user-select` to `none` directly when GPUI creates the canvas, without
relying on the embedding application's stylesheet. This leaves
touch-event handling and the hidden IME textarea unchanged.

Closes DEL-2016

## Validation

- On an iPhone, injecting ordinary inline `-webkit-user-select: none`
prevented the issue; switching it back to `text` reproduced it. No
`!important` was necessary. This tested the equivalent runtime style,
not a rebuilt app containing this commit.
- `cargo fmt -p gpui_web -- --check` passed.
- `RUSTC_BOOTSTRAP=1 cargo check -p gpui_web --target
wasm32-unknown-unknown` passed. The bootstrap flag is required by the
existing `wasm_thread` dependency.

Release Notes:

- Fixed unintended whole-canvas selection when long-pressing in GPUI web
applications on iOS.
2026-09-07 10:06:56 +00:00
Jakub Konka b601a0e716 gpui_web: Disable native canvas touch callouts (#63775)
On iOS, WebKit presents a native touch callout when a user long-presses
a canvas. For GPUI Web this selected the full application canvas while
GPUI independently selected the intended word, producing two pairs of
selection handles, a native edit menu, and haptic feedback.

Set `-webkit-touch-callout: none` on the canvas created by `gpui_web`.
GPUI already owns touch gesture recognition on this surface, so WebKit
should not provide a competing canvas interaction.

Tested with:

- `cargo fmt --check --package gpui_web`
- `RUSTC_BOOTSTRAP=1 cargo check -p gpui_web --target
wasm32-unknown-unknown`
- A Delta Web WASM build using the local Zed checkout
- Manual verification on an iPhone that long-press word selection no
longer selects the full canvas

Release Notes:

- N/A
2026-09-04 18:14:18 +00:00
Jakub Konka 3c1fc637ad ui: Expose keybinding visibility (#63770)
`KeyBinding::set_default_visibility` lets applications suppress
keybinding labels, but the current visibility value is private to
`KeyBinding::render`. Applications that compose related modifier hints
from lower-level UI elements cannot follow the same presentation policy.

Expose the existing visibility query without changing its behavior. This
lets those callers omit their complete hint, including accompanying text
and spacing, while sharing the same application-wide source of truth.

Release Notes:

- N/A
2026-09-04 16:21:48 +00:00
Jakub Konka f15a5dac90 nix: Include corgi patches in build sources (#63644)
The local `scratch` override lives under `corgi-patches`, but the Nix
build source filter omitted that directory. As a result, `nix develop`
failed while loading the patched dependency.

Include `corgi-patches` in the filtered source and preserve the patch
implementation in Crane's dummy dependency source. The latter is
required because `cxx-build` calls `scratch::path` while dependency
artifacts are built.

## Testing

- `nix fmt -- --ci nix/build.nix`
- `nix develop --command true`
- `nix develop --command cargo fmt --check`

Release Notes:

- N/A
2026-09-02 18:13:59 +00:00
Jakub Konka 0d31bb3e06 ui: Allow hiding keybinding labels (#63616)
`KeyBinding` elements currently always render their shortcut labels.
Applications with a touch-oriented interface cannot remove those
keyboard-only visual affordances without changing each consumer or
unregistering the shortcuts themselves.

This adds an application-wide visibility policy to the reusable
`KeyBinding` component, so context menus and other consumers follow the
same setting. Registered keybindings and `aria-keyshortcuts` remain
intact, and labels remain visible by default.

## Testing

- `cargo nextest run -p ui --lib`
- `cargo fmt --check`
- The final unused-override cleanup was not rerun because `nix develop`
currently fails while building the existing `zed-editor-deps`
derivation: `corgi-patches/scratch/Cargo.toml` is absent from its Nix
source.

Release Notes:

- N/A
2026-09-02 17:46:50 +00:00
Jakub Konka a13d872bff util: Embed fs_embed assets with debug-embed (#63583)
Zed's `fs_embed!` macro normally reads assets from the checkout in debug
builds. The new `util/debug-embed` feature is intended to compile those
assets into debug binaries, but it previously changed only the
`rust_embed::Filenames` variant while leaving file loading on the
runtime path.

That breaks downstream workspaces such as Delta: the runtime loader
identifies Delta as the repository root, then looks for Zed grammar
assets under Delta's checkout. Tests consequently panic when language
configuration files cannot be found.

This makes `util/debug-embed` select a compile-time `RustEmbed`
expansion in every profile. Builds without the feature retain live
filesystem loading in debug mode. The runtime iterator no longer depends
on a feature-specific `rust_embed::Filenames` variant, so Cargo feature
unification remains safe when another package enables
`rust-embed/debug-embed` directly. The regression fixture uses a
deliberately invalid runtime path when `debug-embed` is enabled, so it
proves that the embedded path is used rather than passing only because
the Zed checkout contains the test assets.

Testing performed:

- `cargo fmt --all -- --check`
- `cargo nextest run -p util --lib`
- `cargo nextest run -p util --lib --features debug-embed`
- `cargo check -p remote_server --features debug-embed`
- `./script/clippy -p util`
- Delta's previously failing
`tools::edit_file::tests::test_edit_file_rejects_scratch_paths_as_read_only`
against this PR's head commit

Release Notes:

- N/A
2026-09-01 21:42:01 +00:00
Jakub Konka 966ba1f92a gpui: Add long-press gesture recognition (#63561)
GPUI's touch gesture recognizer handles taps and pans, but its
long-press event was only a placeholder. Applications therefore could
not distinguish a deliberate press-and-hold from a tap or scroll using
the portable touch path.

This adds deadline-driven long-press recognition and dispatches a phased
event stream through GPUI's existing capture and bubble listener path. A
listener claims the gesture by preventing the initial event's default
behavior and capturing it for an entity. Unclaimed gestures remain
eligible for the existing tap and pan behaviors, while claimed gestures
receive movement and termination events without also producing taps or
scrolling.

The timer is cancelled when the pending gesture resolves. `gpui_web` now
translates reusable browser pointer identifiers into touch identifiers
that remain unique for each touch lifetime, preventing an old timer from
acting on a newer touch. Native macOS trackpad scrolling remains on its
existing `ScrollWheelEvent` path and does not enter touch gesture
recognition.

Testing performed:

- `cargo fmt --all -- --check`
- `cargo nextest run -p gpui --lib long_press` (10 passed)
- `RUSTC_BOOTSTRAP=1 cargo check -p gpui_web --target
wasm32-unknown-unknown`

Release Notes:

- N/A
2026-09-01 16:28:50 +00:00
Jakub Konka 16da2ea125 gpui: Lock touch scrolling to the dominant axis (#63553)
Touch pans currently preserve small amounts of movement on both axes,
including in the synthetic momentum generated after release. In a nested
scrolling layout, a mostly vertical fling that starts over a
horizontally scrollable child can therefore move the child horizontally
while its ancestor moves vertically.

This locks each touch pan to the dominant axis of its accumulated
movement when it crosses the touch-slop threshold. Initial movement,
predicted updates, release correction, velocity, and momentum are
projected onto that axis, so every scroll listener sees the same
one-dimensional gesture for its full lifetime.

The existing trackpad and wheel behavior remains unchanged; the new rule
is applied by the portable raw-touch recognizer before it emits semantic
scroll events.

Testing:

- `cargo nextest run -p gpui --lib gestures::tests`
- `cargo fmt --all -- --check`
- `./script/clippy -p gpui`
- Built Delta Web for `wasm32-unknown-unknown` with this GPUI worktree
and reached a successful Trunk release build

Release Notes:

- N/A
2026-09-01 14:20:13 +00:00
Jakub Konka a90d3772f8 gpui_wgpu: Reuse glyph image after measuring bounds (#63209)
Release Notes:

- Improved rasterization performance on Linux by caching glyphs after
measuring bounds.
2026-08-25 17:56:09 +00:00
Jakub Konka 8383e32479 Bump tree-sitter to 0.27 and wasmtime to 48.0 (#63169)
Release Notes:

- N/A
2026-08-25 04:10:09 +00:00
Jakub Konka 55fed7ab8d Prewarm Linux font match caches (#63158)
Prewarming cosmic-text font cache completely eliminated expensive
`get_font_matches` calls and thus reducing the time it takes to call
`cosmic_text::shape::ShapeLine::new`.

Release Notes:

- Improved rendering performance on Linux by prewarming font match
caches.
2026-08-24 18:27:55 +00:00
Jakub Konka 9d3ee5bffd gpui_linux: Release X11 client state before close callback (#63089)
Release Notes:

- Fixed double-lease panic on X11 when reacting to WM_DELETE_WINDOW
event.
2026-08-22 20:58:12 +00:00
Jakub Konka be3db5feff gpui_linux: Handle XKB context initialization failure (#62868)
Release Notes:

- Added check for XKB context initialization failure
2026-08-19 11:19:10 +00:00
Jakub Konka 94b4c3ac02 call: Expand audio call diagnostics (#61744)
Closes FR-140

Release Notes:

- Improved call diagnostics with per-participant audio health history
and exportable reports.
2026-07-28 16:56:55 +00:00
Jakub Konka 55b2687062 editor: Check anchor validity for hovered links (#61686)
Closes FR-112

Otherwise, if a multibuffer snapshot changed under the hood for example
one of the paths changed, without doing an explicit validity check, we
would panic during comparison instead.

Release Notes:

- Fixed panic when hovering links during an under-the-hood multibuffer
changes.
2026-07-26 16:37:40 +00:00
Jakub Konka 19d5ca984a gpui_wgpu: Fix bidi paragraph shaping crash (#61651)
Closes FR-133

`cosmic-text`'s BiDi line shaping machinery (`ShapeLine::new`) asserts
that every BiDi paragraph is following the same direction. It turns out
that our `gpui_wgpu` line shaping adapter would not account for that
leading to panics if text contained multiple BiDi paragraphs with
multiple directions. Not super common but worth fixing as the fix is not
super complicated. At the same time, I'd like to point out that there is
a patch submitted to `cosmic-text` that redoes shaping logic so that
this is no longer illegal:
https://github.com/pop-os/cosmic-text/pull/508 If it gets accepted, we
can revert this fix.

Release Notes:
- Fixed panic in `gpui_wgpu` if text contained multiple BiDi paragraphs
with mismatched directions.
2026-07-26 14:31:25 +00:00
Jakub Konka d5a4de9392 gpui_linux: Fix Wayland serial token tracking (#61454)
Closes #58651 
Closes FR-123

https://github.com/zed-industries/zed/pull/50406/ while fixing one issue
regressed serial tracking in Wayland. What happens is we conflated
unrelated serials into a common value which is wrong. For example,
`InputMethod` serial does not come from the same source as `MousePress`
or `KeyPress`, and if Zed is running for a while and the user performs
lots of IME commits (`zwp_text_input_v3.commit`), `InputMethod` will
overtake other serial values and will be incorrectly used for clipboard
authorisation/selection by the compositor such as Mutter or kWin. This
will effectively poison the clipboard making Zed the indefinite owner
until we kill Zed. More concretely, we use `get_latest()` on the serial
tracker to extract *the largest serial REGARDLESS of kind* which is
wrong since not every serial kind comes from the same pool.

Release Notes:

- Fixed copy-paste behaviour in Wayland.
2026-07-22 12:46:55 +00:00
Jakub Konka 0414079168 Only install crash handler when a minidump endpoint is configured (#61384)
Closes FR-130

Builds compiled from source at a release tag report a non-dev release
channel, so they used to install the crash handler and write minidumps
into the shared logs directory. An official Zed launched later would
find and upload those dumps to Sentry, where they can never be
symbolicated (their debug UUID matches no uploaded debug files).

Gate the crash handler on having somewhere to send the dumps: either the
compile-time ZED_MINIDUMP_ENDPOINT baked into official builds, the
runtime ZED_MINIDUMP_ENDPOINT override, or an explicit
ZED_GENERATE_MINIDUMPS opt-in for debugging the crash pipeline locally.

Release Notes:

- N/A
2026-07-21 08:16:15 +00:00
Jakub Konkaandapoorva-01 913a81546d workspace: Fix crash when closing active item mid-update (#61336)
Closes https://github.com/zed-industries/zed/issues/61182

Supersedes https://github.com/zed-industries/zed/pull/61232

Closes FR-128

Release Notes:

- Fixed crash when closing active item while the workspace was
mid-update (double-lease panic).

Co-authored-by: apoorva-01 <vermaapoorva0510@gmail.com>
2026-07-20 12:39:07 +00:00
Jakub Konka 2fff6597d6 gpui_linux: Add support for open_window in headless client (#60359)
This actually makes it possible for Linux headless client to have
working windows for computation (well, we are in headless mode after
all). This also matches macOS headless client behaviour.

Release Notes:

- N/A
2026-07-03 15:20:09 +00:00
Jakub Konka ff9a72fc83 nix: Go around a linker issue on Darwin (#58070)
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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-05-29 12:22:37 +00:00
Jakub Konka efd671682b Revert "Improve ChatGPT subscription response resilience" (#58035)
Reverts zed-industries/zed#57891
2026-05-29 11:23:56 +00:00
Jakub Konka 58567f34fd nix: Fix dev shell on Darwin (#58032)
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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-05-29 08:10:32 +00:00
Jakub Konka b0ffd31c99 ci: Reinstate run-nix label in addition to run-bundling (#58034)
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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

Release Notes:

- N/A
2026-05-29 06:01:22 +00:00
Jakub Konka 84c29531d2 ci: Remove garnix substitutor (#58033)
Release Notes:

- N/A
2026-05-29 05:56:42 +00:00
Jakub Konka 86cc393c04 linux: Bundle libstdc++.so for release (#57132)
Self-Review Checklist:

- [ ] 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)
- [ ] Tests cover the new/changed behavior
- [ ] Performance impact has been considered and is acceptable

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

Release Notes:

- Fixed running Zed on Ubuntu 20.04 installed via the installer by
bundling the required `libstdc++.so`.
2026-05-19 21:43:35 +00:00
Jakub Konka 609ed418e8 language_model: Decouple from Zed-specific implementation details (#52913)
This PR decouples `language_model`'s dependence on Zed-specific
implementation details. In particular
* `credentials_provider` is split into a generic `credentials_provider`
crate that provides a trait, and `zed_credentials_provider` that
implements the said trait for Zed-specific providers and has functions
that can populate a global state with them
* `zed_env_vars` is split into a generic `env_var` crate that provides
generic tooling for managing env vars, and `zed_env_vars` that contains
Zed-specific statics
* `client` is now dependent on `language_model` and not vice versa

Release Notes:

- N/A
2026-04-02 17:06:57 -03:00
Jakub Konka 5f60ef2ab6 nix: Fix build on x86_64-linux (#52917)
Release Notes:

- N/A
2026-04-01 20:50:04 +02:00
Jakub Konka 4c7c7a93e6 language_model: Refactor crate structure and dependencies (#52857)
A couple of things that this PR wants to accomplish:
* remove dependency on `settings` crate from `language_model`
* refactor provider-specific code into submodules - to be honest, I
would go one step further and put all provider-specific bits in
`language_models` instead but I realise we have cloud logic in
`language_model` which uses those too making it tricky
* move anthropic-specific telemetry into `language_models` crate - I
think it makes more sense for it to be there

Anyhow, I would very appreciate if you could have a look @mikayla-maki
and @maxdeviant and lemme know what you think, if you would tweak
something, etc.

Release Notes:

- N/A
2026-04-01 17:44:25 +02:00
Jakub Konka f746bbff0c nix: Fix screen-casting when building Zed with nix (#52690)
Release Notes:

- Fixed screen-casting when building Zed with Nix.
2026-03-30 07:50:20 +02:00
Jakub Konka 930840c462 Bump LiveKit SHA (#52354)
Release Notes:

- N/A
2026-03-24 23:09:31 +01:00
Jakub Konka a92d36fb60 livekit: Remove obsolete separate thread for frame feeder (#51993)
Release Notes:

- N/A
2026-03-20 15:04:21 +01:00
Jakub KonkaandNeel Chotai 8e5b0f56e3 Add screen-sharing support on Wayland/Linux (#51957)
Release Notes:

- Added screen-sharing support on Wayland/Linux.

---------

Co-authored-by: Neel Chotai <neel@zed.dev>
2026-03-19 22:10:42 +01:00
405ac5ebda collab_ui: Add call diagnostics (#51816)
Release Notes:

- Added call diagnostics when collaborating with other Zed users in
collab.

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
Co-authored-by: Danilo Leal <danilo@zed.dev>
2026-03-18 16:25:06 +01:00
Jakub Konka 895b77b504 livekit: Bump livekit version (#51771)
Release Notes:

- Fixed segfault at runtime on aarch64-linux when running static
constructors.
2026-03-17 19:23:56 +01:00
Jakub Konka cddf27b6bd livekit: Use our build of libwebrtc.a (#51433)
Closes #51339

This should address issues with too new libstdc++.so on older/more
conservative distros such as RHEL9.

Release Notes:

- Relaxed requirement for libstdc++.so available on Linux distros.
2026-03-16 10:47:36 +01:00
Jakub Konka abb29dbe62 nix: Correctly handle commitSha == null in nix devshell (#51319)
Release Notes:

- N/A
2026-03-11 18:48:12 +00:00
Jakub Konka 21cecfc219 livekit_client: Always use output device's reported channels num (#51276)
Fixes a panic in livekit's process_reverse_stream for non-matching
channel counts, e.g., upmixing 2->4, or downmixing 2->1.

Release Notes:

- Fixed a panic in livekit when joining a channel using legacy audio
using a device with less or more than 2 channels.
2026-03-11 13:09:08 +01:00
Jakub Konka d4ca11b172 ci: Update workflows/scripts for deploying collab to use clang (#51224)
Release Notes:

- N/A
2026-03-10 22:41:43 +01:00
Jakub KonkaandPiotr Osiewicz 198147be36 livekit_client: Apply correct priority for audio threads (#51178)
Release Notes:

- N/A

Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
2026-03-10 11:50:02 +01:00
Jakub Konka e6827a4990 livekit_client: Route selected audio input/output devices into legacy audio (#51128)
Release Notes:

- Fixed ability to select audio input/output devices for legacy
(non-experimental/rodio-enabled) audio.
2026-03-09 20:50:52 +01:00
Jakub Konka 15512db57e zed: Read ZED_COMMIT_SHA from env var when building (#51115)
Quality-of-life improvement for us Nix users - Zed built via `nix build`
will now correctly the git commit sha in its version

<img width="433" height="298" alt="image"
src="https://github.com/user-attachments/assets/b940ee4a-6914-4410-ba20-b50391282a4e"
/>

Release Notes:

- N/A
2026-03-09 17:02:09 +01:00
Jakub Konka bdbae34e84 ci: Add source list and GPG key manually of ubuntu-toolchain-r (#51102)
Release Notes:

- N/A
2026-03-09 14:55:35 +01:00
Jakub Konka 4d9795b5c7 crashes: Bump minidumper crate to 0.9 (#50937)
Release Notes:

- N/A
2026-03-06 17:06:35 +01:00
Jakub Konka f566a6b1e0 nix: Coerce rel path to cargo wrapper script into abs path (#50919)
This allows you to now re-use our Zed flake in different side projects
with cargo wrapper script having its path correctly resolved.

Say you have this dir structure:

```
$HOME/dev/zed
$HOME/dev/something
```

Then this now works:

```
$ cd $HOME/dev/something
$ nix develop ../zed
$ cargo version
cargo 1.93.0 (083ac5135 2025-12-15)
```

Release Notes:

- N/A
2026-03-06 11:53:14 +01:00
Jakub Konka 790d9fe5bc nix: Hide pipewire lazy trampolines in libwebrtc when linking as SO (#50743)
This would cause a null pointer dereference when trying to open an audio
device in Zed. More context:
https://github.com/NixOS/nixpkgs/pull/478907/changes#r2885943326

cc @cameron1024 

Release Notes:

- Fixed crash when trying to join a channel/test audio on Nix-built Zed
on Linux.
2026-03-04 23:14:06 +01:00
Jakub KonkaandMiguel Raz Guzman Macedo c3af177a7c auto_update_helper: Rollback for all errors including FileNotFound (#50607)
We would mark `FileNotFound` as success and progress the update loop
which does not make much sense.

Release Notes:

- Do not skip update roll back in presence of FileNotFound errors on Windows.

Co-authored-by: Miguel Raz Guzman Macedo <raz@zed.dev>
2026-03-03 17:12:51 +01:00
Jakub Konka b6090dc158 livekit: Correctly handle runtime deps: libva and libva-drm (#50527)
Release Notes:

- N/A
2026-03-03 10:25:01 +01:00
Jakub Konka b3decf6454 ci: Install newer LLVM toolchain on Ubuntu 20.04 runners (#50414)
Release Notes:

- N/A
2026-03-01 00:59:00 +01:00
Jakub Konka 752cd04584 ci: Fix bundling linux (#50375)
Release Notes:

- N/A
2026-02-28 19:59:33 +00:00
Jakub Konka 94ed7d6e04 ci: Use clang/++ in Build docs step to build libwebrtc (#50353)
Release Notes:

- N/A
2026-02-27 22:48:14 +01:00
16853f21af nix: Vendor up-to-date libwebrtc until patched upstream in NixOS (#50352)
Follow-up to #50205

Release Notes:

- N/A

Co-authored-by: Neel Chotai <neel@zed.dev>
Co-authored-by: Josh Robson Chase <josh@robsonchase.com>
2026-02-27 22:43:31 +01:00
Jakub Konka 3dc87b763a Use updated version of our fork of rust-sdks (#50205)
Use updated version of our fork of `rust-sdks` with two minor tweaks
that I also submitted for upstreaming.

Release Notes:

- N/A
2026-02-27 20:22:03 +01:00
Jakub KonkaandPiotr Osiewicz 1c0f15ecb9 workspace: Invert dependency on call crate by extracting into a trait (#49968)
Release Notes:

- N/A

Co-authored-by: Piotr Osiewicz <piotr@zed.dev>
2026-02-24 11:19:34 +00:00
Jakub Konka da0f2f1863 livekit_client: Spawn audio input with high priority (#49887)
Use `BackgroundExecutor::spawn_with_priority(Priority::RealtimeAudio,
fut)` to spawn the audio input thread with correct thread priority much
like we do for audio output. Under-the-hood, `spawn_with_priority +
Priority::RealtimeAudio` boils down to calling `std::thread::spawn` and
setting appropriate thread priority.

Release Notes:

- N/A
2026-02-23 15:24:46 +01:00
Jakub Konka f389729677 Fix cargo test -p editor for Linux/Wayland (#49730)
`cargo test -p editor` now builds on Linux/Wayland

Release Notes:

- N/A
2026-02-20 17:30:55 +01:00
Jakub Konka 8d900471b4 gpui_linux: Fix cargo test on wayland (#49686)
Ensures we can run tests for just `gpui_linux` on Linux/Wayland like so:

```
$ cargo test -p gpui_linux
```

Release Notes:

- N/A
2026-02-20 13:27:09 +01:00
Jakub Konka 0e06137349 buffer_diff: Reduce number of entity clones in base_text_buffer (#49573)
Release Notes:

- Improved split performance by reducing number of entity clones for
very large pre-loaded multibuffers.
2026-02-19 11:57:43 +01:00
Jakub KonkaandLukas Wirth 846b4191c9 editor: More perf work (#49465)
Seems that `SmallVec::clone` is pretty expensive in a generic case, and
specialising it improves the performance quite a bit!

Release Notes:

- Improved performance of different building blocks within the
MultiBuffer.

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-02-18 14:20:30 +01:00
Jakub Konka 08cee47ed3 editor: Batch calls to fold_buffer in ProjectDiff::refresh (#49278)
This change improves performance of project diff in that:
* scrolling in split view for very large diffs (think chromium repo with
`git reset HEAD~1000`) is now very smooth on macOS and fairly smooth on
Linux
* switching from split to unified is very smooth on macOS, and fairly
smooth on Linux

There still remains the case of (severe) hangs when switching from
unified to split however, but it will be addressed in a follow-up PR.

Anyhow, here's the screenshot of the Instruments.app capture of opening
chromium repo in Zed in split view, scrolling a little, moving to
unified, scrolling some more, and moving back to split. Prior to this
change, split -> unified would cause a severe hang, whereas now it's a
hang and thus feels much smoother already (without Instruments profiling
is barely visible). Unified -> split severe hangs are still there but
don't last as long.

<img width="2301" height="374" alt="Screenshot 2026-02-16 at 5 46 23 PM"
src="https://github.com/user-attachments/assets/f687f8d4-cffd-47f1-ada1-f6c4d3ac3cd4"
/>

Release Notes:

- Improved project diff performance when opening very large
diffs/repositories.
2026-02-16 20:58:30 +01:00
Jakub KonkaandCole Miller f4aa279898 util: Always use posix_spawn on macOS even with pre_exec hooks (#49090)
Here's some backstory:
* on macOS, @cole-miller and I noticed that since roughly Oct 2025, due
to some changes to latest macOS Tahoe, for any spawned child process we
needed to reset Mach exception ports
(https://github.com/zed-industries/zed/issues/36754 +
https://github.com/RemiKalbe/zed/commit/6e8f2d2ebe5a93753625a3026aeb996de8cb436b)
* the changes in that PR achieve that via `pre_exec` hook on
`std::process::Command` which then abandons `posix_spawn` syscall for
`fork` + `execve` dance on macOS (we tracked it down in Rust's std
implementation)
* as it turns out, `fork` + `execve` is pretty expensive on macOS
(apparently way more so than on other OSes like Linux) and `fork` takes
a process-wide lock on the allocator which is bad
* however, since we wanna reset exception ports on the child, the only
official way supported by Rust's std is to use `pre_exec` hook
* posix_spawn on macOS exposes this tho via a macOS specific extension
to that syscall `posix_spawnattr_setexceptionports_np` but there is no
way to use that via any standard interfaces in `std::process::Command`
* thus, it seemed like a good idea to instead create our own custom
Command wrapper that on non-macOS hosts is a zero-cost wrapper of
`smol::process::Command`, while on macOS we reimplement the minimum to
achieve `smol::process::Command`  with `posix_spawn` under-the-hood

Notably, this changeset improves git-blame in very large repos
significantly.

Release Notes:

- Fixed performance spawning child processes on macOS by always forcing
`posix_spawn` no matter what.

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-02-13 20:16:11 +01:00
Jakub Konka 86401525ef settings: Get available audio devices lazily when first required (#49115)
Release Notes:

- Get available audio devices lazily when first required.
2026-02-13 20:10:47 +01:00
Jakub KonkaandZed Zippy 0ccfaf9e67 settings: Add ability to select audio input/output devices for collab (#49015)
This PR adds ability to select and test audio input/output devices for
use in collaboration setting (which is what the team at Zed relies
heavily on). Currently, we only ever used whatever the system default is
and it worked well until it didn't - for some reason, when I am on my
Linux laptop, I am unable to force Zed to use my external mic +
headphones via external USB audio interface. With this PR, now I can
list all available devices and select the one I want.

There are still a couple of caveats that we should be aware of:
* I've decided to list *all* available devices meaning on Linux it is
quite possible that you may discover that what your desktop environment
is reporting to you is a significantly shorter list than what your sound
framework/hw is actually exposing. I think this makes sense given my
inexperience with audio drivers/devices and frameworks on various OSes
so that we get full control over what is available with the goal of
being able to come up with some filtering heuristic as we go along.
* We currently populate the list of available audio devices only once at
startup meaning if you unplug your device while you have Zed running
this will not register until you restart Zed which is a PITA. However,
in order to keep the changes manageable I thought it would be best to do
minimal work in this regard now, and iterate on this some more in the
near future. After all, we don't really monitor device changes on any
platform except macOS anyhow, so it might be the case that when I get
round to implementing this I will have the opportunity to tackle both at
the same time.
* In order to get a valid list of all audio devices using `cpal` crate
(which is the building block of `rodio`), I had to bump `cpal` to 0.17,
and pin `rodio` to a more recent commit sha as a result, so if you see
any regressions, lemme know and/or feel free to revert this PR.
* Finally, I've done my best to integrate this with the settings UI, but
I am sure more could be done in terms of styling, etc.

Some screenshots:

<img width="1152" height="949" alt="Screenshot From 2026-02-12 11-40-04"
src="https://github.com/user-attachments/assets/e147c153-1902-49d6-bf68-3ac317a6a7b0"
/>
<img width="1152" height="949" alt="Screenshot From 2026-02-12 11-40-16"
src="https://github.com/user-attachments/assets/b4e9a2f8-b38e-4de0-b910-067cc432b5bc"
/>


Release Notes:

- Added ability to select audio input/output devices as part of
Collaboration page in Settings. Added ability to test selected devices
with a simple playback loop routing input directly into output for
easier debugging of your audio devices.

---------

Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-02-12 14:27:55 +01:00
Jakub Konka c8a7470b63 ztracing: Annotate more callsites that invoke TreeSitter (#47522)
Release Notes:

- N/A
2026-02-11 11:24:04 +00:00
Jakub Konka 11bb6df4aa SplittableEditor: Sync custom blocks between RHS and LHS editors (#48575)
Release Notes:

- Added handling of custom blocks in the RHS editor by creating matching
dummy custom blocks rendered as spacer blocks in the LHS editor when in
split view.
2026-02-06 15:15:57 +01:00
Jakub Konka 3fde9ec689 block_map: Consolidate all companion-related refs into a single CompanionView (#48223)
Release Notes:

- N/A

--

I think it's possible to clean this up further but will withhold until
we land bits necessary to correctly align split view in presence of
custom blocks.
2026-02-03 00:24:42 +01:00
Jakub Konka 89ad1efb23 acp: Skip setting language on secondary diff buffer (#47526)
Mirrors
https://github.com/zed-industries/zed/commit/b3e3a23a5e8fa85e6fdb9f0458185f71ba100ed3.
We skip setting language on the secondary diff buffer which is not
needed and will improve performance and memory usage.

Release Notes:

- Improved memory usage of large ACP thread diff multibuffers.
2026-01-25 09:08:05 +01:00
Jakub Konka b3e3a23a5e git: Skip setting language on git index buffer (#47524)
Skipping setting the language on the git index text buffer improves
snappiness for (very) large git diff multibuffers and also significantly
lower peak and steady-state RSS. When tested on the chromium repo with
`git reset HEAD~1000` and *all* language extensions installed we notice:
* current `main`: peak RSS ~45GB, ss RSS ~39GB
* this patch: peak RSS ~30GB, ss RSS ~27GB

Release Notes:

- Improved memory usage of large git diff multibuffers.
2026-01-23 23:43:25 +00:00
Jakub Konka 4809599e7b Revert " Add vim/emacs modeline support " (#47479)
Reverts zed-industries/zed#44210

I am forced to revert this PR as it completely breaks release builds
with the following panic:

```
thread 'main' (2648653) panicked at crates/rope/src/rope.rs:893:25:
byte index 73 is not a char boundary; it is inside 'স' (bytes 71..74) of `কৰক</translation>
<translation id="9216898458513705996">টেবসমূহ এই ডিভাইচত খোলা `
stack backtrace:
2026-01-23T15:37:48+01:00 INFO  [node_runtime] using Zed managed Node.js at /Users/kubkon/Library/Application Support/Zed/node/node-v24.11.0-darwin-arm64 since system Node.js wasn't found on PATH: cannot find binary path
   0: __rustc::rust_begin_unwind
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/std/src/panicking.rs:698:5
   1: core::panicking::panic_fmt
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/panicking.rs:80:14
   2: core::str::slice_error_fail_rt
   3: core::str::slice_error_fail
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/str/mod.rs:69:5
   4: core::str::traits::<impl core::slice::index::SliceIndex<str> for core::ops::range::Range<usize>>::index
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/str/traits.rs:248:21
   5: <str as core::ops::index::Index<core::ops::range::Range<usize>>>::index
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/str/traits.rs:63:15
   6: <rope::Chunks>::peek
             at /Users/kubkon/dev/zed/crates/rope/src/rope.rs:893:25
   7: <rope::Lines>::next
             at /Users/kubkon/dev/zed/crates/rope/src/rope.rs:1111:45
   8: <project::lsp_store::LspStore>::parse_modeline
             at /Users/kubkon/dev/zed/crates/project/src/lsp_store.rs:4570:43
   9: <project::lsp_store::LspStore>::on_buffer_added
             at /Users/kubkon/dev/zed/crates/project/src/lsp_store.rs:4301:14
  10: <project::lsp_store::LspStore>::on_buffer_store_event
             at /Users/kubkon/dev/zed/crates/project/src/lsp_store.rs:4166:22
  11: <<project::lsp_store::LspStore>::on_buffer_store_event as core::ops::function::FnMut<(&mut project::lsp_store::LspStore, gpui::app::entity_map::Entity<project::buffer_store::BufferStore>, &project::buffer_store::BufferStoreEvent, &mut gpui::app::context::Context<project::lsp_store::LspStore>)>>::call_mut
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/ops/function.rs:166:5
  12: <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe::<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app/context.rs:111:44
  13: <gpui::app::App as gpui::AppContext>::update_entity::<project::lsp_store::LspStore, (), <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}::{closure#0}>::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:2281:26
  14: <gpui::app::App>::update::<(), <gpui::app::App as gpui::AppContext>::update_entity<project::lsp_store::LspStore, (), <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}::{closure#0}>::{closure#0}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:818:22
  15: <gpui::app::App as gpui::AppContext>::update_entity::<project::lsp_store::LspStore, (), <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}::{closure#0}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:2279:14
  16: <gpui::app::entity_map::Entity<project::lsp_store::LspStore>>::update::<(), gpui::app::App, <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}::{closure#0}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app/entity_map.rs:445:12
  17: <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe::<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app/context.rs:111:22
  18: <gpui::app::App>::subscribe_internal::<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <gpui::app::context::Context<project::lsp_store::LspStore>>::subscribe<project::buffer_store::BufferStore, project::buffer_store::BufferStoreEvent, <project::lsp_store::LspStore>::on_buffer_store_event>::{closure#0}>::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:964:25
  19: <alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>> as core::ops::function::FnMut<(&dyn core::any::Any, &mut gpui::app::App)>>::call_mut
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/alloc/src/boxed.rs:2012:9
  20: <gpui::app::App>::apply_emit_effect::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:1407:21
  21: <gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain::<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}
             at /Users/kubkon/dev/zed/crates/gpui/src/subscription.rs:132:17
  22: <alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain::<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>::{closure#0}
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/alloc/src/collections/btree/map.rs:1177:37
  23: <alloc::collections::btree::map::ExtractIfInner<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>, core::ops::range::RangeFull>>::next::<<alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>::{closure#0}, alloc::alloc::Global>
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/alloc/src/collections/btree/map.rs:2036:16
  24: <alloc::collections::btree::map::ExtractIf<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>, core::ops::range::RangeFull, <alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>::{closure#0}> as core::iter::traits::iterator::Iterator>::next
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/alloc/src/collections/btree/map.rs:2002:20
  25: <alloc::collections::btree::map::ExtractIf<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>, core::ops::range::RangeFull, <alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>::{closure#0}> as core::iter::traits::iterator::Iterator>::fold::<(), core::iter::traits::iterator::Iterator::for_each::call<(usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>), core::mem::drop<(usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>)>>::{closure#0}>
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/iter/traits/iterator.rs:2602:34
  26: <alloc::collections::btree::map::ExtractIf<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>, core::ops::range::RangeFull, <alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>::{closure#0}> as core::iter::traits::iterator::Iterator>::for_each::<core::mem::drop<(usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>)>>
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/iter/traits/iterator.rs:828:14
  27: <alloc::collections::btree::map::BTreeMap<usize, gpui::subscription::Subscriber<(core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>>::retain::<<gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain<<gpui::app::App>::apply_emit_effect::{closure#0}>::{closure#1}>
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/alloc/src/collections/btree/map.rs:1177:46
  28: <gpui::subscription::SubscriberSet<gpui::app::entity_map::EntityId, (core::any::TypeId, alloc::boxed::Box<dyn for<'a, 'b> core::ops::function::FnMut<(&'a dyn core::any::Any, &'b mut gpui::app::App), Output = bool>>)>>::retain::<<gpui::app::App>::apply_emit_effect::{closure#0}>
             at /Users/kubkon/dev/zed/crates/gpui/src/subscription.rs:130:21
  29: <gpui::app::App>::apply_emit_effect
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:1405:14
  30: <gpui::app::App>::flush_effects
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:1308:31
  31: <gpui::app::App>::finish_update
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:830:18
  32: <gpui::app::App>::update::<core::result::Result<(), anyhow::Error>, <gpui::app::App as gpui::AppContext>::update_entity<project::buffer_store::BufferStore, core::result::Result<(), anyhow::Error>, <project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}::{closure#0}::{closure#3}>::{closure#0}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:819:14
  33: <gpui::app::App as gpui::AppContext>::update_entity::<project::buffer_store::BufferStore, core::result::Result<(), anyhow::Error>, <project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}::{closure#0}::{closure#3}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:2279:14
  34: <gpui::app::async_context::AsyncApp as gpui::AppContext>::update_entity::<project::buffer_store::BufferStore, core::result::Result<(), anyhow::Error>, <project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}::{closure#0}::{closure#3}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app/async_context.rs:65:13
  35: <gpui::app::entity_map::WeakEntity<project::buffer_store::BufferStore>>::update::<gpui::app::async_context::AsyncApp, core::result::Result<(), anyhow::Error>, <project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}::{closure#0}::{closure#3}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app/entity_map.rs:750:15
  36: <project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}::{closure#0}::<i32>
             at /Users/kubkon/dev/zed/crates/project/src/buffer_store.rs:683:18
  37: <gpui::app::context::Context<project::buffer_store::BufferStore>>::spawn::<<project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}::{closure#0}::<i32>
             at /Users/kubkon/dev/zed/crates/gpui/src/app/context.rs:244:52
  38: <gpui::app::App>::spawn::<<gpui::app::context::Context<project::buffer_store::BufferStore>>::spawn<<project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:1532:44
  39: <scheduler::executor::spawn_local_with_source_location::Checked<<gpui::app::App>::spawn<<gpui::app::context::Context<project::buffer_store::BufferStore>>::spawn<<project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}> as core::future::future::Future>::poll
             at /Users/kubkon/dev/zed/crates/scheduler/src/executor.rs:393:64
  40: <async_task::raw::RawTask<scheduler::executor::spawn_local_with_source_location::Checked<<gpui::app::App>::spawn<<gpui::app::context::Context<project::buffer_store::BufferStore>>::spawn<<project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}>, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>, <scheduler::executor::ForegroundExecutor>::spawn<<gpui::app::App>::spawn<<gpui::app::context::Context<project::buffer_store::BufferStore>>::spawn<<project::buffer_store::LocalBufferStore>::open_buffer::{closure#1}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}, core::result::Result<gpui::app::entity_map::Entity<language::buffer::Buffer>, anyhow::Error>>::{closure#0}>::{closure#0}, scheduler::RunnableMeta>>::run
             at /Users/kubkon/.cargo/git/checkouts/async-task-e468f817236eac43/b4486cd/src/raw.rs:296:17
  41: <async_task::runnable::Runnable<scheduler::RunnableMeta>>::run
             at /Users/kubkon/.cargo/git/checkouts/async-task-e468f817236eac43/b4486cd/src/runnable.rs:788:18
  42: gpui::platform::mac::dispatcher::trampoline
             at /Users/kubkon/dev/zed/crates/gpui/src/platform/mac/dispatcher.rs:248:14
  43: <unknown>
  44: <unknown>
  45: <unknown>
  46: <unknown>
  47: <unknown>
  48: <unknown>
  49: <unknown>
  50: <unknown>
  51: <unknown>
  52: <unknown>
  53: <unknown>
  54: <unknown>
  55: <unknown>
  56: <unknown>
  57: <unknown>
  58: <gpui::platform::mac::platform::MacPlatform as gpui::platform::Platform>::run
             at /Users/kubkon/dev/zed/crates/gpui/src/platform/mac/platform.rs:473:17
  59: <gpui::app::Application>::run::<zed::main::{closure#9}>
             at /Users/kubkon/dev/zed/crates/gpui/src/app.rs:192:18
  60: zed::main
             at /Users/kubkon/dev/zed/crates/zed/src/main.rs:419:9
  61: <fn() as core::ops::function::FnOnce<()>>::call_once
             at /rustc/ded5c06cf21d2b93bffd5d884aa6e96934ee4234/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
```

cc @ConradIrwin @elmarco
2026-01-23 15:24:37 +00:00
Jakub Konka 23c7d60f1e ztracing: Enable memory profiling and callstack sampling (#47052)
While at it, annotate more functions that are potentially related to
language parsing in buffers.

Also, on macOS, in order to actually have callstack frames properly
recorded by Tracy, you need to manually run `dsymutil` on the binary.

Release Notes:

- N/A
2026-01-17 19:29:19 +00:00
Jakub Konka 5596e86a95 git: Annotate more functions and blocks with tracing spans (#46642)
Release Notes:

- N/A
2026-01-12 21:56:08 +00:00
Jakub Konka f92d93aeee language_models: Make wording for setting env vars consistent (#46240)
Release Notes:

- N/A
2026-01-07 10:26:49 +00:00
Jakub Konka 6907c9e659 workspace: Auto-switch git context when focus changed (#45354)
Closes #44955 

Release Notes:

- Fixed workspace incorrectly automatically switching Git
repository/branch context in multi-repository projects when repo/branch
switched manually from the Git panel.
2025-12-19 13:54:30 +01:00
Jakub Konka 66faf88e9f Fix self-referential symbolic link (#45265)
Release Notes:

- N/A
2025-12-18 17:26:20 +01:00
Jakub Konka c824e81695 helix: Map Zed's specific diff and git-related to goto mode (#45006)
Until now, Helix-mode users would have to rely on Vim's `d *` behaviour
which cannot be reliably replicated with Helix's default delete
behaviour and so I believe that remapping this functionality to Helix's
goto mode is a better fit.

Release Notes:

- Added custom mappings for Zed specific diff and git-related actions to
Helix's goto mode:
  * `g o` - toggle selected diff hunks
  * `g O` - toggle staged
  * `g R` - restore change
  * `g u` - stage and goto next diff hunk
  * `g U` - unstage and goto next diff hunk
2025-12-16 16:41:27 +00:00
Jakub Konka 6bff3f3533 buffer_diff: Fix git gutter incorrectly showing for ignored files (#43776)
Closes #43734
Closes #43698

Release Notes:

- Fixed git gutter incorrectly showing up for ignored files.
2025-11-29 08:08:51 +01:00
Jakub KonkaandCole Miller 61e9025370 git: Move git-blame outside of git job queue (#43565)
We restructured `struct Repository` a bit so that it now stores a shared
task of `enum RepositoryState`. This way, we can now re-use it outside
of the git job queue when spawning a git job a standalone bg task. An
example here would be `git-blame` that does not require any file locks
and is not susceptible to git job ordering.

As a result of this change, loading (and modifying) a file that contains
a huge git history will no longer block other git operations on the repo
such as staging/unstaging/committing.

Release Notes:

- Improved overall git experience when loading buffers with massive git
history where they would block other git jobs from running (such as
staging/unstaging/commiting). Now, git-blame will run separately from
the git job queue on the side and the buffer with blame hints when
finished thus unblocking other git operations.

Co-authored-by: Cole Miller <cole@zed.dev>
2025-11-27 21:07:26 +00:00
Jakub Konka aeb660bd8f git: Bring back auto-commit suggestions (#43470)
This got accidentally regressed in
https://github.com/zed-industries/zed/pull/42149.

Release Notes:

- Fixed displaying auto-commit suggestions for single staged entries.
2025-11-25 16:26:44 +00:00
Jakub KonkaandCole Miller 3d1ebe4b58 git: Handle git pre-commit hooks separately (#43285)
We now run git pre-commit hooks before we commit. This ensures we don't
run into timeout issues with askpass delegate and report invalid error
to the user.

Closes #43157

Release Notes:

- Fixed long running pre-commit hooks causing committing from Zed to
fail.

Co-authored-by: Cole Miller <cole@zed.dev>
2025-11-22 00:33:32 +01:00
Jakub Konka d22af5eb95 git: Clear pending ops for remote repos (#43098)
Release Notes:

- N/A
2025-11-19 22:47:51 +01:00
Jakub Konka 90117a636c git: Put pending ops container out of snapshot (#43061)
This also fixes staging checkbox flickering.

Release Notes:

- Fixed staging checkbox flickering sporadically in the Git panel.
2025-11-19 14:56:10 +00:00
Jakub Konka b72fbc4555 Revert "git: Remove JobStatus from PendingOp in favour of in-flight p… (#42970)
…runing (#42955)"

This reverts commit 0b7150449a.

Release Notes:

- N/A
2025-11-18 13:30:40 +00:00
Jakub Konka 0b7150449a git: Remove JobStatus from PendingOp in favour of in-flight pruning (#42955)
The idea is that we only store running (`!self.finished`) or finished
(`self.finished`) pending ops, while everything else (skipped, errored)
jobs are pruned out immediately. We don't really need them in the grand
scheme of things anyway.

Release Notes:

- N/A
2025-11-18 10:22:34 +00:00
Jakub Konka 02cfad8ab6 git_panel: Fix buffer header checkbox not showing partially staged files (#42718)
Release Notes:

- Fixed buffer header controls (staging checkbox) not showing partially
staged files
2025-11-14 12:55:04 +00:00
Jakub Konka 5115b6c25d git_panel: Fix StageAll/UnstageAll not working when panel not in focus (#42708)
Release Notes:

- Fixed "Stage All"/"Unstage All" buttons from not working when git
panel is not in focus
2025-11-14 10:42:32 +01:00
Jakub Konka 0c8d001ffb git_panel: Fix Stage All/Unstage All ignoring partially staged files (#42677)
Release Notes:

- Fix "Stage All"/"Unstage All" not affecting partially staged files
2025-11-13 23:57:05 +01:00
Jakub Konka 10055b050c git_panel: Fix partially staged changes not showing up (#42530)
Release Notes:

- N/A
2025-11-12 15:13:29 +01:00
Jakub Konka d4555d7a0b git: Add askpass delegate to git-commit handlers (#42239)
In my local setup, I always enforce git-commit signing with GPG/SSH
which automatically enforces `git commit -S` when committing. This
changeset will now show a modal to the user for them to specify the
passphrase (if any) so that they can unlock their private key for
signing when committing in Zed.

<img width="1086" height="948" alt="Screenshot 2025-11-07 at 11 09
09 PM"
src="https://github.com/user-attachments/assets/ac34b427-c833-41c7-b634-8781493f8a5e"
/>


Release Notes:

- Handle automatic git-commit signing by presenting the user with an
askpass modal
2025-11-10 07:57:50 +00:00
Jakub Konka 198373c1eb shell_env: Wrap error context in format! where missing (#42267)
Release Notes:

- N/A
2025-11-08 15:46:01 +00:00
Jakub Konka edcf851165 Remove invalid assertion in editor (#42210)
Release Notes:

- N/A
2025-11-07 17:36:10 +00:00
Jakub Konka bcf859c777 git: Make long-running git staging snappy in git panel (#42149)
Previously, staging a large file in the git panel would block the UI
items until that operation finished. This is due to the fact that
staging is a git op that is locked globally by git (per repo) meaning
only one op that is modifying the git index can run at any one time. In
order to make the UI snappy while letting any pending git staging jobs
to finish in the background, we track their progress via `PendingOps`
indexed by git entry path. We have already had a concept of pending
operations however they existed at the UI layer in the `GitPanel`
abstraction. This PR moves and augments `PendingOps` into the model
`Repository` in `git_store` which seems like a more natural place for
tracking running git jobs/operations. Thanks to this, pending ops are
now stored in a `SumTree` indexed by git entry path part of the
`Repository` snapshot, which makes for efficient access from the UI.

Release Notes:

- Improved UI responsiveness when staging/unstaging large files in the
git panel
2025-11-07 07:34:06 +01:00
Jakub Konka 74f4aee3be util: Log JSON with envs if failed to deserialize (#41894)
Release Notes:

- N/A
2025-11-04 15:30:26 +01:00
Jakub Konka c7d7eb0da2 terminal: Resolve env based on the project dir on the target (#41867)
Prior to this change we would always resolve envs when spawning a new
terminal window based on the inherited CLI environment. This works fine
as long as we open a new Zed instance in the terminal when using it
locally only. When using Zed connected to a remote server, it would not
be meaningful however. WIth this change, we correctly ping the remote
for the project-local envs and use that instead. This change should also
fix a pesky issue when updating Zed - after Zed restarts, opening a new
terminal window will not run `direnv` for example.

Release Notes:

- N/A
2025-11-04 09:52:28 +01:00
Jakub Konka 99dfe3dd16 git: Make GitPanel more responsive to long-running staging ops (#41667)
Currently, this only applies to long-running individually selected
unstaged files in the git panel. Next up I would like to make this work
for `Stage All`/`Unstage All` however this will most likely require
pushing `PendingOperation` into `GitStore` (from the `GitPanel`).

Release Notes:

- N/A
2025-10-31 22:47:49 +01:00
Jakub Konka 4979d63298 remote: Support building x86_64-linux-musl proxy in nix-darwin (#41291)
This change adds two things to our remote server build
process:
1. It now checks if all required tooling is installed before using it or installing it on demand. This includes checks for `rustup` and `cargo-zigbuild` in your `PATH`.
2. Next, if `ZED_BUILD_REMOTE_SERVER` contains `musl` and `ZED_ZSTD_MUSL_LIB`
is set, we will pass its value (the path) to `cargo-zigbuild` as `-C
link-arg=-L{path}`.

Release Notes:

- N/A
2025-10-28 06:58:09 +01:00
Jakub Konka 9ca4bec14d remote: Fall back to SCP if SFTP fails (#41255)
Fixes https://github.com/zed-industries/zed/issues/41260

After experimenting and reading through the implementation of OpenSSH
stack on Windows, it looks like batch mode precludes use of passwords.
In the listing
https://github.com/PowerShell/openssh-portable/blob/b8c08ef9da9450a94a9c5ef717d96a7bd83f3332/sshconnect2.c#L417,
the last field of each `Authmode` struct is a pointer to the config
value that *disables* that particular mode. In this case, `keyboard`
(interactive) and `password` modes are both disabled if batch mode is
used. We should therefore fall back to `scp` if `sftp` fails rather than
to fail outright.

Release Notes:

- N/A
2025-10-27 15:01:13 +01:00
Jakub Konka 33533109b9 Use ShellKind::try_quote whenever we need to quote shell args (#41104)
Re-reverts
https://github.com/zed-industries/zed/commit/d84a81e5e38e7d1eadf78e2bcf7a1f32eae034d4
with fixes

Release Notes:

- N/A
2025-10-24 18:19:53 +02:00
Jakub Konka ca151efa72 remote: Do not compress remote by default when building from source (#40994)
Release Notes:

- N/A
2025-10-23 21:26:34 +02:00
Jakub Konka 6a9304e531 Revert "Use ShellKind::try_quote whenever we need to quote shell args" (#41022)
Reverts zed-industries/zed#40912

Closes https://github.com/zed-industries/zed/issues/41010
2025-10-23 16:06:47 +00:00
Jakub KonkaandLukas Wirth d84a81e5e3 Use ShellKind::try_quote whenever we need to quote shell args (#40912)
Using `shlex` unconditionally is dangerous as it assumes the underlying
shell is POSIX which is not the case for PowerShell, CMD, or Nushell.
Therefore, whenever we want to quote the args we should utilise our
helper `util::shell::ShellKind::try_quote` which takes into account
which shell is being used to actually exec/spawn the invocation.

Release Notes:

- N/A

---------

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
2025-10-23 06:44:42 +02:00