## Objective
Fixes an issue where language servers provided by extensions are not
included in the settings schemas served by remote servers. When
connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (dev servers,
multi-workspace reopen, git worktree picker), setup-N servers never
received any extension sync, so their schemas omitted extension-provided
language servers, breaking language support for remote development.
## Solution
Three changes ensure that language servers provided by extensions are
included in the settings schemas served by remote servers:
1. **Register connections opened via
`open_remote_project_with_existing_connection` with the extension
store**: dev servers, multi-workspace reopen, and the git worktree
picker now register their connections with the extension store so that
extensions are synced to those servers. Previously only the
`open_remote_project` flow did this, so setup-N servers never received
any extension sync and their schemas omitted extension language servers.
2. **Emit `ExtensionsInstalledChanged` from `HeadlessExtensionStore`
after sync and install complete**: this allows the remote process to
invalidate its cached settings schemas. The local `ExtensionStore`
already emitted this event; without it, the remote schema cache stayed
stale for the lifetime of the server process.
3. **Include available LSP adapters in the project settings schema**:
this matches the user settings schema (this was fixed for `settings` in
#46766 but never applied to `project_settings`).
## Testing
- Manually verified that after connecting to a remote server via the
`open_remote_project_with_existing_connection` flow (including dev
servers and the git worktree picker), extension language servers appear
in the schema served by the remote server.
- Verified that `ExtensionsInstalledChanged` is emitted after sync and
install complete, and that the remote schema cache is correctly
invalidated and rebuilt.
- Verified that the `project_settings` schema includes the available LSP
adapters, matching the behavior of the user settings schema.
- Reviewers should focus on the multi-workspace reopen and git worktree
picker flows (the two previously unregistered flows) to confirm that
extension language servers are correctly synced and appear in the
schema.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
## Showcase
**Server / Project** — before the fix
<img width="1061" height="749" alt="image"
src="https://github.com/user-attachments/assets/d6c5459f-58fb-4769-a701-f6fb317adc37"
/>
**Local**
<img width="1119" height="449" alt="image"
src="https://github.com/user-attachments/assets/fb30a1e2-74f0-4439-a25f-1022ed164074"
/>
---
Release Notes:
- Fixed an issue where language servers provided by extensions were
missing from settings schemas served by remote servers.
---------
Co-authored-by: vancez <vancez@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
# Objective
Fixes#43932.
Extensions built with `zed_extension_api` 0.0.6 or 0.1 pass the absolute
worktree root in `SettingsLocation.path`. After #38744 changed core
settings locations to `RelPath`, `RelPath::new` returns an error for
that absolute value. The conversion produces `None`, so
`ProjectSettings::get` falls back to global settings. This regressed the
behavior fixed in #10859.
The current LaTeX and Typst extensions both use API 0.1, matching the
two extension surfaces reported in the issue.
# Solution
For the 0.0.6 and 0.1 WIT adapters, treat the legacy path as the
worktree root (`RelPath::empty()`) and preserve the worktree ID. API 0.2
and later already send an empty relative path, so their behavior is
unchanged.
The two version adapters each have a regression test for the legacy
absolute-root input.
# Testing
- `cargo test -p extension_host
settings_location_targets_the_worktree_root` (2 passed)
- `cargo test -p extension_host -- --skip
extension_store_test::test_extension_store_with_test_extension` (10
passed; the skipped fixture needs the `wasm32-wasip2` target, which is
not installed in the local Homebrew Rust toolchain)
- `cargo clippy -p extension_host --all-targets -- -D warnings`
- `cargo fmt --check`
- `cargo build -p zed`
End-to-end check with an isolated `--user-data-dir`, a trusted folder
worktree, LaTeX extension 0.2.3, and texlab 5.26.0:
- Zed 1.16.1 sent the global sentinel for both startup and a live
project-settings edit.
- This branch sent the project sentinel on startup.
- Changing the project sentinel from V2 to V3 produced a new
`workspace/didChangeConfiguration` with V3, and texlab's follow-up
`workspace/configuration` request also returned V3.

# Self-review checklist
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
- [x] Tests cover the new behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- Fixed project-level language server settings being ignored by
extensions built with extension API versions before and including
v0.1.0.
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Refactors our query loading to instead have an enum of supported queries
and load the query files themselves in parallel, where possible.
We will use this to warn extension authors when unsupported queries are
present, as we no longer want to ship those as part of the extension.
It also now enforces one file per supported query - only one extension
currently utilizes this feature and was undocumented previously, so I
decided in favor of removing it here, since this will help with
enforcing extensions to just ship query files we actually support in the
future. The extension has also been migrated so that it does not break
with this effort
Side-effect of this change is that we now load both embedded and
external languages up to at least 10%/5% faster, since the files are now
read in parallel as opposed to sequentially one by one.
Release Notes:
- N/A
This adds a dedicated `AvailableLanguages` struct in preparation for a
more cabable language matching based on a given language config. No
functional changes, just shuffling some code around for this round.
Also made the LanguageMatcher non-cloneable in favor of wrapping it in
an Arc, since cloning is rather expensive for this and having a
reference is sufficient in all cases right now.
Release Notes:
- N/A
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
This is necessary to remove some `util` dependencies from crates, as
well as better sharing for our projects. This also includes the WIP
AbsPath abstraction as well as some bug fixes from internal tooling.
Release Notes:
- N/A or Added/Fixed/Improved ...
Closes#21822
The issue is closed already, but it was requested to provide the
`hard_tabs` boolean param.
Follow-up to #52175
Reviewed by @maxdeviant (it already bumped the settings path to v0.8.0,
so this `hard_tabs` change only needs 2 files, 2-3 lines of code
additions).
## Context
Exposes `hard_tabs` from `AllLanguageSettings` to the Extension
API's `LanguageSettings` struct. Currently, only `tab_size` and
`preferred_line_length` are available to extensions, which prevents
language extensions (e.g., Go, C++) from reading the user's hard tabs
preference and forwarding it to their language server or formatter
(e.g., as rustfmt.hard_tabs or clang-format.UseTab).
Related:
https://github.com/zed-industries/zed/issues/21822#issuecomment-4139809956
## How to Review
Small change — follow how `tab_size` is plumbed through:
1. WIT definition (`language-settings` record)
2. `extension_api` Rust struct
3. Host-side bridge conversion
The new field follows the exact same pattern.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
- Compile-time verified via WIT bindings; no runtime behavior change
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
# Objective
Fix a Windows CI flake in `extension_host
extension_store_test::test_extension_store_with_test_extension`, which
panicked in GPUI's leak detector with three leaked `LspStore` handles
([example
run](https://github.com/zed-industries/zed/actions/runs/28871529605/job/85635418351)).
## Solution
`LspAccess::ViaLspStore` held a strong `Entity<LspStore>`, cloned into
three `ExtensionHostProxy` registrations by `language_extension::init`.
The proxy sits inside an `Arc` cycle (proxy →
`LanguageServerRegistryProxy` → `LanguageRegistry` →
`ExtensionLspAdapter` → `WasmExtension` → `WasmHost` → proxy), so
whenever an extension LSP adapter was registered at app-drop time, the
cycle pinned the `LspStore` entity after its owning `Project` dropped.
The flake was purely timing: extension reload toggles the adapter
registration, and an unclean LSP pipe shutdown on Windows shifted
teardown into the pinned window.
`ViaLspStore` now holds a `WeakEntity<LspStore>`, upgraded at its sole
use site (`remove_language_server`), skipping the stop task when the
store is gone — matching the existing `ViaWorkspaces` semantics. A dead
store is the expected terminal state after the owning project drops, so
no error is logged or propagated. `Project`/`HeadlessProject` remain the
sole long-term owners of `LspStore`, which is already the convention
everywhere else (e.g. `json_schema_store`, the `lsp_store` message
handlers).
## Testing
- Ran `cargo nextest run -p extension_host
extension_store_test::test_extension_store_with_test_extension` locally:
passes.
- The flake is timing-dependent (reproduced on Windows CI), so a local
pass doesn't prove absence; the fix removes the only strong non-owner
handle, which the leak detector reported.
## Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and
[icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
---
Release Notes:
- N/A
---------
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
Resolves#56068
Remote extension sync previously only sent extensions that can run
remotely: language servers, debug adapters, and debug locators. That
excluded language-only extensions such as TOML, so a remote session
could have Tombi synced and loaded while the remote language registry
still lacked TOML's language definition.
This diff keeps the remote sync set narrow: it starts from extensions
that can run remotely, then adds the extension that defines each
language referenced by those extensions' language servers. This installs
the TOML language config alongside Tombi without syncing unrelated
language-only extensions, allowing project settings schemas to recognize
language names like TOML and allowing remote language servers to attach
to buffers whose language is provided by a separate extension.
Release Notes:
- Fixed remote sessions failing to recognize languages provided by
language-only extensions.
---------
Co-authored-by: Finn Evers <finn.evers@outlook.de>
This will improve local dev installation times as well as CI times by a
lot (I measured it once and for some extensions, it might save us up to
60% of CI time. It will similarly help locally).
I also moved the debug adapter schema validation to the other
validations, as it felt it makes more sense to check there as opposed to
doing this during the compilation step.
Release Notes:
- Improved dev extension installation times for language extensions with
multiple grammars or language servers.
Release Notes:
- When stopping all language servers, Zed will now no longer restart
language servers when language files change until the user restarts all
language servers explicitly
This PR drops the `Architecture::x86` variant within the extension API.
Reason for this being that
- Zed itself is not shipped for 32 bit and thus this variant is never
actually constructed
- we don't support a Node runtime in 32 bit environments
- basically all language and context servers do not ship 32 bit variants
Thus, this PR removes support for this variant, as currently, extension
authors always have to return an error for the missing 32 bit support of
their binaries. With this, this will no longer be needed.
Lastly, this removes one space of too much indentation I found whilst
doing these changes. Very visible in the GitHub UI luckily.
Release Notes:
- Removed support for extensions downloading language servers, debuggers
and MCP servers on 32-bit architecture. Extensions may still work if you
manually specify a path to an appropriate binary, but will not succeed
when attempting to download a binary based on the current systems 32-bit
architecture.
Self-Review Checklist:
- [X] I've reviewed my own diff for quality, security, and reliability
- [N/A] 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:
- Removed support for ACP extensions. Installed ACP extensions will be
migrated to use the ACP servers as provided by the ACP registry instead.
---------
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
Co-authored-by: Marshall Bowers <git@maxdeviant.com>
This fixes extension installation when Zed's cache directory and data
directory are on different filesystems or mount points. On my Linux
system, `~/.cache` is a separate btrfs subvolume so it can be excluded
from system snapshots, while `~/.local/share` is on the main home
subvolume. Installing extensions failed because extension archives were
unpacked under `paths::temp_dir()` and then renamed into the installed
extensions directory.
The error showed up as:
```text
2026-05-11T17:08:57+02:00 INFO [extension_host] installing extension dockerfile latest version
2026-05-11T17:08:58+02:00 ERROR [crates/extension_host/src/extension_host.rs:842] Invalid cross-device link (os error 18)
```
Linux rename(2) returns EXDEV (os error 18) across filesystem
boundaries. This is the same class of issue addressed for settings
writes in #8437 and later generalized in
557fe8f720. The regression was introduced
by #54355, which made extension updates safer by unpacking into a
temporary directory before renaming into place.
This change creates the temporary unpack directory inside the installed
extensions directory instead. That keeps the final rename on the same
filesystem as the destination while preserving the existing
direct-unpack fallback if creating the temporary directory fails. A
possible alternative would be to create a dedicated temporary install
directory under `extensions/`, alongside `extensions/installed/`. I
chose, however, to keep the temporary directory directly beside the
final destination because that matches the destination-local temp-file
approach used in the earlier fixes referenced above.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
No separate issue. The change is small and includes the reproduction
context here. I did not add a regression test because the failure
depends on cache and data directories being on different
filesystems/subvolumes; this was verified manually by reproducing EXDEV
when installing extensions with `~/.cache` on a separate btrfs
subvolume, then confirming the patch fixes extension installation.
Release Notes:
- Fixed installing extensions when Zed's cache and data directories are
on different filesystems.
This PR introduces native LSP support for Bash by integrating
`bash-language-server`. Combined with the existing Tree-sitter grammar,
Zed now provides a complete, out-of-the-box development experience for
shell scripting.
The implementation is very similar to other npm-managed language
servers. With `shellcheck` installed, standard LSP features—including
diagnostics, code actions, go-to-definition, find-references, and code
completion—work as expected.
Since I am not a frequent user of Bash, I have intentionally limited
this implementation to a standard, "out-of-the-box" setup. I lack the
hands-on experience to identify specific pain points or advanced LSP
features that might require custom integration, so I've avoided adding
any speculative or specialized configurations, especially within the
`LspAdapter` trait.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [ ] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes#51917
Release Notes:
- Added built-in language server support for Bash
---------
Co-authored-by: Finn Evers <finn@zed.dev>
Following our incident earlier, I noticed a report that mentioned their
extension was uninstalled upon update which made them stumble across the
issue for our outage.
The reason for this was that currently, whenever we install extension
updates, we _first_ removed the old directory and _then_ went ahead and
downloaded the new version. This would in turn obviousy lead to issus
where something malfunctioned during the update/install download -
whether that is an issue on our side with the servers or an issue on the
users side when they have a poor network connection or lose that.
This PR changes this - we now do the entirety of the download on a
background task, unpack the archive into a temporary directory if
possible and then proceed with removing the old extension contents and
moving the new contents only _after_ everything prior succeeded.
I also moved this off of the main thread since there is no reason to do
this there as well as the `Drop` impl of a `TempDir` doing some blocking
work on the main thread otherwise.
Release Notes:
- Made extension updates more resilient to network and upstream failures
The DAP TCP transport layer was hardcoded to `Ipv4Addr`, so IPv6
addresses like `fd00::a` in a debug config's `connect.host` always
failed with `hostname must be IPv4: invalid IPv4 address syntax`.
Replaced `Ipv4Addr` with `IpAddr` and `SocketAddrV4` with `SocketAddr`
across the `task`, `dap`, `dap_adapters`, and `project` crates. The WASM
extension API still uses `u32` for the host field to avoid a breaking
WIT interface change; IPv4 round-trips through extensions as before.
Fixes#52237
Release Notes:
- Fixed DAP TCP transport rejecting IPv6 addresses when connecting to
remote debug adapters.
---------
Co-authored-by: moktamd <moktamd@users.noreply.github.com>
When extracting gzip tar files, the `GzipDecoder` was being pinned
directly over the response body stream. This caused issues because the
decoder needs to read the entire stream into memory before the `Archive`
can be created and used.
Buffer the decompressed bytes into a `Vec` first, then create the
decoder over that in-memory buffer to ensure all data is available when
needed.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes [Java extension issue
222](https://github.com/zed-extensions/java/issues/222)
Testing:
**Automated:**
- `cargo test -p extension_host
test_extension_store_with_test_extension` — integration test that
exercises the full `download_file` → `GzipTar` → `extract_tar_file` path
through a WASM extension with a `FakeHttpClient` serving a real gzipped
tar archive. Passed.
**Manual:**
- Built and ran Zed with `cargo +nightly run`, deleted and reinstalled
the Java extension. The extension's language server download completed
successfully and all expected files were extracted.
Release Notes:
- Fixed extension `download_file` with `GzipTar` silently dropping
archive entries by buffering the full HTTP response before extraction,
matching the approach already used for extension installation. See
https://github.com/zed-industries/zed/blob/0a256eda7a7004985f1dddfee7bf822f66bc6ce0/crates/extension_host/src/extension_host.rs#L761
Hit a flake in this test in
https://github.com/zed-industries/zed/actions/runs/24555985980/job/71792549618.
Ran for 1000 iterations and hit a second race, now also hopefully fixed.
Self-Review Checklist:
- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- [x] Tests cover the new/changed behavior
- [x] Performance impact has been considered and is acceptable
Closes #ISSUE
Release Notes:
- N/A or Added/Fixed/Improved ...
This PR bumps Tree-sitter for this crash fix
https://github.com/tree-sitter/tree-sitter/pull/5475
Release Notes:
- Fixed a crash that could occasionally occur when parsing files using
certain language extensions
🫡
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:
- Removed legacy Text Threads feature to help streamline the new agentic
workflows in Zed. Thanks to all of you who were enthusiastic Text Thread
users over the years ❤️!
---------
Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
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 #ISSUE
Release Notes:
- N/A
When debugging a remote SSH connection, I came across an unformatted
format string in the output log. I changed the raw `.context(fmt)` call
to a `.with_context(|| format!(fmt))`. I ran a quick sweep through the
codebase to identify and fix two other instances of the same issue.
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
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#21822
## Context
Exposes `preferred_line_length` from `AllLanguageSettings` to the
Extension
API's `LanguageSettings` struct. Currently only `tab_size` is available
to
extensions, which prevents language extensions (e.g. Dart) from reading
the
user's preferred line length and forwarding it to their language server
(e.g. as `dart.lineLength`).
Related: https://github.com/zed-extensions/dart/issues/2
## How to Review
Small change — follow how `tab_size` is plumbed through:
1. WIT definition (`language-settings` record)
2. `extension_api` Rust struct
3. Host-side bridge conversion
The new field follows the exact same pattern.
## Self-Review Checklist
<!-- Check before requesting review: -->
- [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
- Compile-time verified via WIT bindings; no runtime behavior change
- [x] Performance impact has been considered and is acceptable
Release Notes:
- N/A
This will help with test times (in some cases), as nextest cannot figure
out whether a given rdep is actually an alive edge of the build graph
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
This adds checks to the extension CLI to ensure that tasks and semantic
token rules are actually valid for the compiled extensions.
Release Notes:
- N/A
(This should be merged after #48332)
This PR exposes the LSP settings schema functionality to extensions,
allowing them to provide JSON schema for `initialization_options` and
`settings` fields to enable autocomplete in settings files.
New extension API methods (v0.8.0+):
- `language_server_initialization_options_schema`
- `language_server_settings_schema`
Both methods return an optional JSON string conforming to JSON schema.
Older extension versions gracefully return `None`.
Release Notes:
- Added support for settings schemas for the next version of the
extension API so that settings autocompletion can be provided for
language server settings.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: MrSubidubi <finn@zed.dev>
## Summary
- Route `zed:extension/github` in `since_v0_0_4` to the `since_v0_6_0`
bindings
- Call `latest_github_release` through `since_v0_6_0` for compatibility
with the v0.0.4 extension API
Release Notes:
- Fixed backward compatibility for v0.0.4 extension API GitHub bindings.
We see a number of crashes in Sentry that appear to be crashes in
wasmtime.
This shouldn't happen, as wasmtime is designed to run untrusted code
"safely".
Looking into this, it seems likely that the problem is that we race with
wasmtime
when installing signal handlers. If wasmtime's handlers are installed
before ours,
then any signals that it intends to handle (like out of bounds memory
access) will
reach our handlers before its; which causes us to assume the app has
crashed.
This changes fixes our crash handler initialization to ensure we always
create
our signal handler first, and reverts a previous attempt to fix this
from #40883
Closes #ISSUE
Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Linux: Fixed crashes that could happen due to our crash handler
erroneously catching signals intended for wasmtime.
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>
## Summary
When the v0.8.0 extension API was forked in #44025, the five DAP
dispatcher methods in `wit.rs` were not updated to handle
`Extension::V0_8_0`. Because `V0_8_0` is listed before `V0_6_0` in the
enum, the wildcard `_ =>` catch-all fires first, causing all DAP calls
to bail with `"not available prior to v0.6.0"` for any extension
targeting the v0.8.0 API.
The DAP WIT interface is identical between v0.6.0 and v0.8.0, so the
handler code is the same — this just adds the missing match arms for:
- `call_get_dap_binary`
- `call_dap_request_kind`
- `call_dap_config_to_scenario`
- `call_dap_locator_create_scenario`
- `call_run_dap_locator`
This follows the same pattern used by every other method in the
`Extension` impl block, which already handles both `V0_8_0` and
`V0_6_0`.
## Test plan
- Verified that an extension targeting `zed_extension_api` v0.8.0 with
DAP support can successfully start a debug session (previously failed
with `"dap_request_kind not available prior to v0.6.0"`)
Release Notes:
- Fixed DAP (Debug Adapter Protocol) methods failing for extensions
targeting the v0.8.0 extension API.
Round 2 of #46269 with conflicts properly resolved.
This came up a few times across various extensions. With us about to
ship a new API version soon, it might be worth to add.
Release Notes:
- N/A
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Some language servers include local symbols (e.g., local variables,
parameters) in workspace symbol results. Without the `containerName`
information, these symbols lack context information, making it difficult
to distinguish them from top-level definitions and hindering efficient
symbol lookup.
This change exposes the `container_name` field from LSP
[`SymbolInformation`](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#symbolInformation)
to the extension API, allowing language server extensions to access
`symbol.container_name` in `label_for_symbol` and provide meaningful
context when rendering symbol labels.
Note: The `container_name `field is added to all extension API versions
because they seem to share the same underlying Rust types via wasmtime
bindgen. The field is optional, so existing extensions would remain
compatible as far as I understand.
Closes #ISSUE
Release Notes:
- Added `container_name` field to `lsp::Symbol`, accessible via the
extension API's `label_for_symbol` function
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
This allows extensions to add more than one snippet file whilst keeping
it backwards compatible.
Release Notes:
- Added support for specifying multiple snippets paths in extensions.
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings
- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.
This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.
Closes#4762
Release Notes:
- Add basic emacs/vim modeline support.
Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements
---------
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
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
Closes https://github.com/zed-industries/zed/issues/34402
Release Notes:
- MCP servers can now be run on the remote server when using remote
development. This can be enabled by setting the `"remote": true`
property in the settings entry for the MCP server.
---------
Co-authored-by: localcc <kate@zed.dev>
Co-authored-by: Lukas Wirth <me@lukaswirth.dev>