Skip to content

dev_container: Align compose project name with reference CLI and recover from mixed-version duplicates - #6

Draft
antont wants to merge 173 commits into
fix-docker-ps-multi-containerfrom
fix-compose-project-name-derivation
Draft

dev_container: Align compose project name with reference CLI and recover from mixed-version duplicates#6
antont wants to merge 173 commits into
fix-docker-ps-multi-containerfrom
fix-compose-project-name-derivation

Conversation

@antont

@antont antont commented Apr 18, 2026

Copy link
Copy Markdown
Owner

Stacked on zed-industries#54068 (detection). When reviewing, read zed-industries#54068 first.

In antont/zed fork this PR is retargeted to base fix-docker-ps-multi-container so the stack is visible; when upstreamed, rebase onto main and set base to zed-industries:main.

Summary

This PR ships two related changes together, because the second keeps the first from regressing upgraders:

  1. Match @devcontainers/cli's full getProjectName precedence. Replaces safe_id_lower(devcontainer.json's name) with the same five-step chain the reference CLI walks (see src/spec-node/dockerCompose.ts in devcontainers/cli):

    1. COMPOSE_PROJECT_NAME from the local environment.
    2. COMPOSE_PROJECT_NAME= in the workspace .env file.
    3. Top-level name: on the merged compose config, when at least one fragment declared it explicitly.
    4. ${workspaceFolderBasename}_devcontainer — only when the first compose file's directory is <workspace>/.devcontainer/.
    5. Otherwise, the plain basename of the first compose file's directory (no suffix).

    The old Zed implementation diverged at every one of those inputs: any user setting COMPOSE_PROJECT_NAME, shipping a .env with one, declaring a top-level compose name:, or pointing dockerComposeFile outside .devcontainer/ (e.g. "../docker-compose.yml") got a different project namespace than the CLI and VS Code, producing two compose projects for the same folder.

  2. Mixed-version tiebreak. When check_for_existing_container's label-based lookup returns two candidates (because a pre-fix Zed left a container under the legacy project name alongside a CLI-style one), prefer the container whose com.docker.compose.project label matches the value the new derivation produces. Log the ignored legacy orphan. Two non-canonical candidates still surface MultipleMatchingContainers (dev_container: Detect error state when docker ps returns duplicate containers zed-industries/zed#54068's safety net).

Without the tiebreak, the derivation fix would turn the existing silent-duplicate state on upgrade into a hard MultipleMatchingContainers error. Shipping both makes the change a transparent upgrade in the common case while preserving CLI-parity in the long tail.

As a concrete example exercising rule 4 — a folder devcontainer-compose-test/ with "name": "Compose Duplicate Repro" and docker-compose.yml in .devcontainer/, no .env and no explicit compose name::

  • Old Zed → compose_duplicate_repro
  • CLI / VS Code → devcontainer-compose-test_devcontainer
  • New Zed → devcontainer-compose-test_devcontainer (matches CLI)
  • On upgrade, if both already exist: new Zed reuses devcontainer-compose-test_devcontainer, logs the compose_duplicate_repro orphan.

Adds a small sanitize_compose_project_name() helper that implements the CLI's sanitization rules (lowercase + strip [^-_a-z0-9]) — notably preserving hyphens, which safe_id_lower would have replaced with underscores.

Adds two helpers used by the precedence walk:

  • parse_dotenv_compose_project_name — line scan extracting COMPOSE_PROJECT_NAME=… from the workspace .env, matching the subset the CLI's regex dotenv reader recognizes.
  • compose_fragment_declares_name — parses a compose fragment via serde_yaml and checks for a name key on the root mapping (block, quoted, or flow style all work), matching the CLI's own yaml.load. docker compose config always injects name: devcontainer into its merged output when no fragment declared one, so rule 3 needs to distinguish the user-provided case from the injected default — this helper supplies that signal. On YAML parse failure it returns "not declared" (rule 4 applies), matching the CLI's fallback.

project_name() becomes async and fallible (async fn project_name(&self) -> Result<String, DevContainerError>) so it can load the .env file and each compose fragment via self.fs.load. Four call sites now .await? the derivation. Real I/O errors on the .env read propagate as FilesystemError (matching the CLI's narrow ENOENT/EISDIR swallow); fragment-rescan read errors are logged and skipped (matching the CLI's broader try/catch over its fragment read + parse).

The name field is still used as the features image-tag prefix (generate_features_image_tag); only the compose project namespace is decoupled from it.

Adds a compose_project field on DockerConfigLabels, serde-renamed to com.docker.compose.project, consumed by the tiebreak's inspect call.

New dependency: serde_yaml_ng

This PR adds a new workspace dependency on serde_yaml_ng = "0.10" (a YAML parser), pulled in only by dev_container. Its entire use is one call in compose_fragment_declares_name that parses a compose fragment to check whether the root mapping has an explicit name: key. That signal is required by getProjectName rule 3 — docker compose config injects a default name: devcontainer into its merged output whenever no fragment declared one, so the only way to distinguish the user-declared case from the injected default is to re-parse each fragment the user wrote. The reference CLI does this via yaml.load. We originally tried a line-based scanner here; a reviewer correctly pointed out (zed-industries#9 in the commit list) that it missed quoted keys and flow-style root mappings, so the scanner was replaced with a real YAML parse.

serde_yaml_ng rather than serde_yaml because dtolnay's serde_yaml is archived and publishes as 0.9.34+deprecated. serde_yaml_ng (acatton) is an active minimal fork with attribution intact, declared drop-in compatibility with serde_yaml's Value/from_str/Mapping API, and no outstanding community concerns. The other notable fork, serde_yml (sebastienrousseau), is also archived and has community concerns about stripped attribution from the dtolnay original — skipped on both counts.

Happy to take guidance here — swap to a different crate, keep the deprecated serde_yaml, or anything else the reviewers prefer.

Why

Full write-up with verified fixtures and captured output: #5

Three failure modes from the same root cause, all resolved by this change:

  1. Interop — opening a folder in both Zed and devcontainer up (or Zed on one version and VS Code on another) creates two compose projects with identical devcontainer.local_folder + devcontainer.config_file labels, breaking the spec's uniqueness invariant.
  2. Cross-worktree silent db/volume reuse — if multiple git worktrees share a devcontainer.json with the same name, Zed uses the same compose project for all of them; Compose reuses stateful siblings (db, cache, localstack) by config-hash, so worktree B silently inherits worktree A's database. Fixture + captured output: https://github.com/antont/zed-devcontainer-db-share-repro
  3. Mixed-version Zed sessions — Rust impl landed in stable v0.232.2 (2026-04-15, Dev containers native implementation zed-industries/zed#52338). Older Zed (≤v0.231.x) shelled out to @devcontainers/cli so it used the reference derivation. The collision shows up when new Zed has already created a container under the name-field project and a CLI-derivation tool (old Zed, devcontainer up, VS Code) runs against the same folder afterwards — the reverse order does not duplicate, because new Zed's label-first lookup reuses the existing CLI-style container. So a v0.231.x → v0.232+ upgrade by itself isn't a reproducer; a mixed-version rhythm where the name-field container was created first is. The tiebreak lets new Zed transparently adopt the canonical container when both already exist.

This PR is a companion to zed-industries#54068 (duplicate-detection on the lookup side). This one fixes the root cause and handles graceful recovery; that one catches remaining genuine ambiguity on the label-lookup path.

Migration / compatibility

Existing Zed-created containers (under the old safe_id_lower(name) project) are still found via check_for_existing_container, which looks them up by devcontainer.local_folder + devcontainer.config_file labels, not by project name. So on first run after upgrade, the existing container is reused; the tiebreak covers the case where both a legacy container and a CLI-style container coexist. No user action required.

Test plan

  • cargo test -p dev_container --lib — 86 passed, including:
    • sanitize_compose_project_name_matches_cli_rules
    • --project-name assertion added to test_spawns_devcontainer_with_docker_compose
    • check_for_existing_container_prefers_canonical_compose_project
    • check_for_existing_container_errors_when_none_canonical
    • should_deserialize_inspect_with_compose_project_label
    • derive_project_name_env_wins_over_everything
    • derive_project_name_dotenv_wins_over_compose_and_fallback
    • derive_project_name_compose_name_wins_over_fallback
    • derive_project_name_skips_compose_name_when_not_explicitly_declared
    • derive_project_name_omits_suffix_when_compose_file_outside_devcontainer_dir
    • compose_fragment_declares_name_detects_top_level_name_key (covers block, quoted-key, and flow-style roots, plus parse failure → not-declared)
    • is_missing_file_error_only_accepts_notfound_and_notadirectory
  • cargo fmt --all — clean
  • cargo clippy --workspace --release --all-targets --all-features -- --deny warnings — clean
  • End-to-end with fixture antont/zed-devcontainer-compose-test:
    • Build zed from this branch.
    • Clean slate: docker ps -a --filter "label=devcontainer.local_folder=$PWD" -q | xargs -r docker rm -f
    • zed --dev-container /Users/antont/src/devcontainer-compose-test → Zed creates container under project devcontainer-compose-test_devcontainer (was compose_duplicate_repro before the fix).
    • devcontainer up --workspace-folder $PWD → CLI reports the same containerId Zed created; no second compose project is introduced.
    • Captured: devcontainer-compose-test_devcontainer-app-1 (ID b0cfb5836f92), composeProjectName: "devcontainer-compose-test_devcontainer" reported by both tools.

Commits

  1. Derivation RED — pins --project-name expectation to the CLI derivation, no production change. Commit message captures the exact failure output.
  2. Derivation GREEN — implements rule 4 (the ${folderBasename}_devcontainer branch), adds the CLI-parity sanitization helper + unit test. Remaining rules land in commits 7–8.
  3. Tiebreak RED — failing multi-match test with canonical vs legacy inspect overrides.
  4. Tiebreak GREEN — adds pick_canonical_container, routes the MultipleMatchingContainers error arm through it.
  5. Serde coverage — deserialization test for the com.docker.compose.project label rename, confirming the new typed field round-trips.
  6. Readability — collapses the passthrough arms in check_for_existing_container to result => result so the multi-match interception stands out as the only non-trivial arm. No behavior change.
  7. Precedence RED — pins the full five-step CLI precedence via a pure derive_project_name helper and five focused tests (one per rule plus the rule-3 edge case). Commit message captures the RED output.
  8. Precedence GREEN — fills in derive_project_name, adds parse_dotenv_compose_project_name and compose_fragment_declares_name scanners, and converts project_name() to async so it can load .env and each compose fragment.
  9. Tighten helpers to CLI semantics — addresses two review findings: (a) .env read failures now propagate unless the error is NotFound/NotADirectory (matching the CLI's narrow ENOENT/EISDIR swallow), preventing silent fallback to a non-canonical project name when a workspace has an unreadable .env; (b) compose_fragment_declares_name now parses fragments as YAML via serde_yaml rather than line-scanning, so quoted keys and flow-style root mappings are honored just like the CLI's yaml.load. project_name() becomes Result<_, DevContainerError>; four call sites propagate with ?.
  10. Swallow read errors in compose fragment rescan — review follow-up on Copy element debug JSON to the clipboard on cmd-alt-i zed-industries/zed#9. The reference CLI's getProjectName wraps fragment readFile+yaml.load in one try/catch that ignores every failure (dockerCompose.ts 663-673); the prior commit propagated non-missing read errors as FilesystemError, which would fail the whole devcontainer flow for fragments the CLI would have silently skipped. Switches the loop to log + continue on any fs.load failure. The stricter .env policy stays — it mirrors a separate, narrower CLI branch.

Commits 1–2, 3–4, and 7–8 each follow a TDD RED/GREEN pattern; each RED/GREEN commit message captures the transition output.

Release Notes:

  • Fixed dev container Docker Compose project name now matches the full getProjectName precedence from the reference devcontainer CLI (COMPOSE_PROJECT_NAME in the environment, then in the workspace .env, then an explicit top-level name: on the merged compose config, then the basename of the first compose file's directory — with the _devcontainer suffix only when that directory is <workspace>/.devcontainer). This prevents duplicate containers when the same folder is opened with both Zed and the devcontainer CLI / VS Code, or with both new Zed and older Zed (≤v0.231.x) that shelled out to the CLI. On first run after the fix, if both a legacy-named and a CLI-style container exist, Zed now reuses the canonical one and logs the orphan instead of erroring.

@antont
antont force-pushed the fix-compose-project-name-derivation branch from ac74dfe to 9ffed07 Compare April 18, 2026 15:23
@antont
antont changed the base branch from main to fix-docker-ps-multi-container April 18, 2026 15:23
antont added a commit that referenced this pull request Apr 18, 2026
Introduce `pick_canonical_container`, a thin recovery layer above
`find_process_by_filters`. When the multi-match detection from zed-industries#54068
trips, inspect each candidate and prefer the one whose
`com.docker.compose.project` label equals `self.project_name()`. Zero
or ≥2 canonical matches still fall through to the
`MultipleMatchingContainers` error, preserving the safety net; only the
unambiguous-recovery case is intercepted.

This makes the compose-project-name fix from PR #6 a transparent
upgrade: users migrating past v0.231.x to v0.232+ on an existing
Zed-managed project had one container under the legacy
`safe_id_lower(name)` project. After the derivation change new Zed
creates one under the canonical `${folder}_devcontainer`. Without the
tiebreak, the label-based lookup sees both and errors out; with it,
Zed reuses the canonical one and logs the orphan's id so users can
clean up on their own schedule.

The multi-match detection itself (`parse_find_process_output`,
`MultipleMatchingContainers`, its Display impl, the pass-through arm
in `start_dev_container_with_config`) stays byte-identical with
zed-industries#54068.

Updates the pre-existing
`check_for_existing_container_errors_when_multiple_match` test to
supply non-canonical inspect overrides, so it still exercises the
safety-net fall-through now that the path inspects each candidate.

    running 3 tests
    test devcontainer_manifest::test::check_for_existing_container_errors_when_multiple_match ... ok
    test devcontainer_manifest::test::check_for_existing_container_errors_when_none_canonical ... ok
    test devcontainer_manifest::test::check_for_existing_container_prefers_canonical_compose_project ... ok

    test result: ok. 78 passed; 0 failed (full crate)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@antont antont changed the title dev_container: Align compose project name with reference CLI dev_container: Align compose project name with reference CLI and recover from mixed-version duplicates Apr 19, 2026
antont added a commit that referenced this pull request Apr 19, 2026
Introduce `pick_canonical_container`, a thin recovery layer above
`find_process_by_filters`. When the multi-match detection from zed-industries#54068
trips, inspect each candidate and prefer the one whose
`com.docker.compose.project` label equals `self.project_name()`. Zero
or ≥2 canonical matches still fall through to the
`MultipleMatchingContainers` error, preserving the safety net; only the
unambiguous-recovery case is intercepted.

This makes the compose-project-name fix from PR #6 a transparent
upgrade: users migrating past v0.231.x to v0.232+ on an existing
Zed-managed project had one container under the legacy
`safe_id_lower(name)` project. After the derivation change new Zed
creates one under the canonical `${folder}_devcontainer`. Without the
tiebreak, the label-based lookup sees both and errors out; with it,
Zed reuses the canonical one and logs the orphan's id so users can
clean up on their own schedule.

The multi-match detection itself (`parse_find_process_output`,
`MultipleMatchingContainers`, its Display impl, the pass-through arm
in `start_dev_container_with_config`) stays byte-identical with
zed-industries#54068.

Updates the pre-existing
`check_for_existing_container_errors_when_multiple_match` test to
supply non-canonical inspect overrides, so it still exercises the
safety-net fall-through now that the path inspects each candidate.

    running 3 tests
    test devcontainer_manifest::test::check_for_existing_container_errors_when_multiple_match ... ok
    test devcontainer_manifest::test::check_for_existing_container_errors_when_none_canonical ... ok
    test devcontainer_manifest::test::check_for_existing_container_prefers_canonical_compose_project ... ok

    test result: ok. 78 passed; 0 failed (full crate)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@antont
antont force-pushed the fix-compose-project-name-derivation branch from 303ebca to 5244b33 Compare April 19, 2026 10:52
pdrgds and others added 20 commits April 20, 2026 08:45
…ed-industries#53100)

Fixes zed-industries#42787

## Summary

- When "Go to Definition" navigates into a dependency (e.g. `.venv/`,
`node_modules/`), the save dialog for new files defaulted to that
directory
- `most_recent_active_path` now checks the `read_only_files` setting and
skips matching paths, falling back to the next eligible path, the
worktree root, or the home directory

## Design tradeoffs

We considered three approaches:

1. **Filter by `is_ignored`/`is_hidden`/`is_external` on worktree
entries** — catches `.venv` when gitignored or when it's a dotfile, but
also false-positives on directories like `.github/workflows/` that users
intentionally edit.

2. **Use preview tab status** — "Go to Definition" opens files as
preview tabs, so skipping preview paths targets the right intent. But it
doesn't work when preview tabs are disabled, and the signal is transient
(preview status changes as you interact with tabs).

3. **Use `read_only_files` setting** (this PR) — an explicit user
declaration of "I never want to edit files here." If you can't edit
them, you don't want to save new files next to them either. This is the
clearest signal of intent and respects user configuration. The tradeoff
is that `read_only_files` is empty by default, so users need to
configure it. But the kind of user bothered by the save dialog
defaulting to a dependency directory is the same kind of user who
already configures `read_only_files` (see
[zed-industries#46827](zed-industries#46827) for an
example).

## Test plan

- [x] Manual test: configured `read_only_files: ["**/.venv/**"]`, opened
project, Go to Definition into `.venv`, created new file — save dialog
defaults to project root
- [x] Added `test_most_recent_active_path_skips_read_only_paths`
- [x] All existing workspace tests pass

Release Notes:

- Fixed save dialog defaulting to dependency directories (e.g. `.venv/`,
`node_modules/`) after using Go to Definition, when those directories
are configured as `read_only_files`.

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
Super small update changing two instances where
`DiagnosticSeverity::HINT` was set to use the color for "info".

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 zed-industries#45637

Release Notes:

- Fixed various instances of hint level diagnostics using the color
designated for info
…ed-industries#54183)

This PR makes Zed only have one worktree picker, as opposed to a flavor
of it in the title bar and another in the agent panel. It then moves it
to the title bar, making it always present, so that its trigger is
separate from the branch picker (which now contains only two views:
branches and stashes). For the worktree picker, I'm mostly favoring the
behavior we've introduced in the agent-panel-flavored version.

It also updates the title bar settings migration to use the JSON
`migrate_settings` helper instead of a shallow Tree-sitter rewrite, so
old `show_branch_icon = true` values are promoted to
`show_branch_status_icon = true` across root, platform, release-channel,
and profile settings scopes.

- [x] Move worktree creation logic to the `git_ui` crate to make this
more generic and less agent-specific
- [x] Double-check the remote use case and ensure nothing broke there
- [x] Improve the UX for the detached HEAD state; better invite people
to create a branch
- [x] Migrate `show_branch_icon = true` to `show_branch_status_icon =
true` across nested settings scopes

Suggested .rules additions

When migrating renamed settings keys that can appear in platform
overrides, release-channel overrides, or profiles, prefer the JSON
`migrations::migrate_settings` helper over shallow Tree-sitter key
rewrites unless tests explicitly cover every nested scope that can
contain the key.

Release Notes:

- Improved migration of the title bar branch status icon setting.

---------

Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
Co-authored-by: Ben Brandt <benjamin.j.brandt@gmail.com>
…cation (zed-industries#54297)

Closes zed-industries#52587

Release Notes:

- Improved the Dev Container suggestion notification to include the
project name, with the full path shown as a tooltip.
See:
https://github.com/zed-extensions/ocaml/blob/626cf8e76103fb2d8ea62fc06095df669aca4441/languages/mlx/config.toml#L3

Self-Review Checklist:

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

Release Notes:

- Associate .mlx extensions with OCaml
…es#54306)

This change contains a number of fixes to make kept_rate more intuitive.
It also adds a CLI utility to print debug info on how the metric is
computed.

Release Notes:

- N/A
…ries#54317)

This is just a refinement given it's pretty common for menus under
ellipsis icon buttons to also open as a context-menu through the mouse's
right-button click. This should make it slightly more convenient to
interact with this menu.

Release Notes:

- N/A
…52525)

Update all direct calls to `Editor::inline_blame_popover::take` to now
be calls to `Editor::hide_blame_popover` as this ensures that the
popover is also not shown in case its task still hasn't finished.

This fixes a bug where the inline git blame popover could be shown even
after the user had opened a modal. 

Release Notes:

- Fixed the inline Git blame popover sometimes appearing after opening a
modal.

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
Fix two issues with reasoning support in the Copilot provider:

- Responses API path: use the user's thinking_effort setting instead of
hardcoding Medium effort
- Chat Completions path: compute and pass thinking_budget when thinking
is enabled, instead of unconditionally setting it to None

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

Closes zed-industries#52140

Release Notes:

- Fixed a bug where copilot wouldn't use the thinking level the user's
have set

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
…zed-industries#54123)

Stacked on top of zed-industries#54112
This is part 2 of 3 towards zed-industries#51197
More details from the original PR zed-industries#53551

This PR includes the changes from zed-industries#54112 , im not sure how to avoid
that, my understanding is that after that one is merged, this PR can be
rebased onto main and everything will be correct. You can also view the
version of this that does reflect the changes more directly here:
feitreim#1

## Changes

In this PR I added a more general string matching functionality to
`fuzzy_nucleo`, in order to have proper testing for this, I also changed
the command palette, tab switching picker, branch picker, and recent
projects picker to use this new implementation. I think the command
palette change in particular is awesome, just super nice to vaguely
gesture at the command i want and have it pop right up.

The main change here and departure from
zed-industries#37123 is realizing that the
primary reason for the regressions is actually how nucleo handles smart
case, the old `fuzzy` crate only uses the smart case argument to score
things differently, while nucleo actually filters on the case, eg. with
smart case query "Apple" wouldnt match "apple". To get around this we
always pass `CaseMatching::Ignore` to nucleo and implement the same
score modifications from fuzzy in our code.

There is a performance cost to that, of course, but from my testing it
is fairly static, not growing as the size increases, so maybe a query
takes 35 µs instead of 25 µs, but a query that takes 800 µs will only
take 820 µs.

Benchmark:
| kind | query | size | nucleo | fuzzy | nucleo/fuzzy |
  |---|---|---:|---:|---:|---:|
  | string | 1-word | 100 | 9.15 µs | 24.6 µs | 0.37× |
  | string | 1-word | 1000 | 150.2 µs | 207.2 µs | 0.72× |
  | string | 1-word | 10000 | 1.34 ms | 2.07 ms | 0.65× |
  | string | 2-word | 100 | 5.16 µs | 2.94 µs | 1.75× |
  | string | 2-word | 1000 | 29.0 µs | 11.0 µs | 2.63× |
  | string | 2-word | 10000 | 210.6 µs | 55.5 µs | 3.79× |
  | string | 4-word | 100 | 2.57 µs | 2.33 µs | 1.10× |
  | string | 4-word | 1000 | 6.98 µs | 5.85 µs | 1.19× |
  | string | 4-word | 10000 | 20.0 µs | 12.0 µs | 1.66× |

When I added the 4-word queries to the benchmarks I was actually really
concerned that the performance would be awful, making it unsuitable for
the command palette especially. However, I think due to the CharBag
pre-filtering when the query is longer, the performance is actually way
better than the 2 word case.

Video:


https://github.com/user-attachments/assets/3cd7221b-424f-4fd3-8df1-5543dcc340a3

Self-Review Checklist:

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

Release Notes:

- Improved fuzzy matching in the command palette, branch picker, tab
switcher, and recent projects picker to support multi-word queries.

---------

Co-authored-by: Yara <git@yara.blue>
…es#54316)

Follow up to zed-industries#52730. 

This PR adds a boolean setting `limit_content_width` in the Agent Panel
settings that allows turning off the content max-width entirely, which
was added for better readability. We had a handful of requests for it,
so it feels fair.

<img width="500" alt="Screenshot 2026-04-20 at 8  57@2x"
src="https://github.com/user-attachments/assets/d2540b35-3fa8-4424-895d-dc499ac4839c"
/>

Release Notes:

- Agent: Added a new `limit_content_width` setting in the agent panel
that allows turning off the content max-width limit.
…Codestral (zed-industries#53691)

Codestral and copilot has a custom menu being built out. While the
common menu has the configure provider quick setting, the custom menu
doesn't have them. however it is a neat feature to have and quickly
switch it out.

Furthermore, copilot has an option of "Use zed AI" when copilot isn't
signed in. Instead add the complete list and configure provider when it
is not signed in

Before
<img width="256" height="588" alt="Screenshot 2026-04-11 at 4 46 47 PM"
src="https://github.com/user-attachments/assets/7de1c09c-a7a0-46d1-9572-fa5e970c77a8"
/>
<img width="230" height="480" alt="Screenshot 2026-04-11 at 4 47 00 PM"
src="https://github.com/user-attachments/assets/7075538f-1966-4ece-985f-b5e0d1d50f4a"
/>

After
<img width="259" height="663" alt="Screenshot 2026-04-11 at 5 02 48 PM"
src="https://github.com/user-attachments/assets/31094f7b-8efa-488a-87d8-1998e554ec74"
/>
<img width="242" height="580" alt="Screenshot 2026-04-11 at 5 03 21 PM"
src="https://github.com/user-attachments/assets/aba8ba09-1fbd-4c43-ba1f-af7ed51551a4"
/>
<img width="224" height="253" alt="Screenshot 2026-04-11 at 5 03 44 PM"
src="https://github.com/user-attachments/assets/108e7b6f-1216-4a2c-b0c0-7be3dc5438b0"
/>


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 NA

Release Notes:

- added configure provider menu item to copilot and codestral

---------

Signed-off-by: Pranav <pranav10121@gmail.com>
Co-authored-by: Ben Kunkle <ben@zed.dev>
…ges (zed-industries#54310)

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 zed-industries#54309 

Release Notes:

- Fixed an outline panel issue where the pin/unpin tooltip could show
stale text after toggling.
…es#54307)

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 zed-industries#54305 
Release Notes:

- Fixed inconsistent keybinding hint casing in the outline panel
(“Toggle Panel With …”) by using standard keybinding rendering.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
…d-industries#54284)

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 zed-industries#54283 

Release Notes:

- Fixed: Git graph commit detail header now uses “1 Changed File” when
exactly one file changed, and “N Changed Files” otherwise, instead of
always saying “Changed Files”.

---------

Co-authored-by: Kunall Banerjee <hey@kimchiii.space>
…ries#54300)

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 zed-industries#54299 

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
## Context

`ctrl-n` / `cmd-n` doesn't work on the Welcome tab. The global binding
lives under `Workspace && !Terminal` (macOS) and similar contexts that
don't include Welcome. The fix just adds the same binding to the Welcome
context block on all three platforms — same approach the font-size and
recent-project shortcuts already use there.

Closes zed-industries#52426

## Demo

### Before:




https://github.com/user-attachments/assets/69becde8-25d2-45e3-9e7c-416b7937bd17

### After:




https://github.com/user-attachments/assets/6d9ede76-7adb-4527-bfef-c18d5b8a4fb4









## How to review

One line added per platform keymap file. Check that `ctrl-n` / `cmd-n`
maps to `workspace::NewFile` in the `Welcome` block of:
- `assets/keymaps/default-macos.json`
- `assets/keymaps/default-linux.json`
- `assets/keymaps/default-windows.json`

## Self-review checklist

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

Release Notes:

- Fixed `ctrl-n` / `cmd-n` (New File) not working on the Welcome tab

Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
This PR adds support for rendering **Netpbm** image formats (`.pbm`,
`.ppm`, `.pgm`) within Zed's built-in image viewer.

These formats are particularly useful for projects that want minimal
external dependencies, a common scenario in academic environments and
low-level graphics programming.

Since the underlying `image` crate and `GPUI` already provide support
for these codecs, this change explicitly exposes the `Pnm` variant
within `gpui::ImageFormat` by mapping it to `image::ImageFormat::Pnm`.

## Screenshots/Examples

Below is an example of `.pbm`, `.ppm`, and `.pgm` files being rendered
correctly in the image preview (images taken from
https://filesamples.com):
<img width="1917" height="1012" alt="pnm_example"
src="https://github.com/user-attachments/assets/0056133f-908c-4c91-ba9d-53aef0657b05"
/>



Release Notes:
  - Added support for PNM image previews (`.pbm`, `.ppm`, `.pgm`).
…#53195)

## 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 zed-industries#52942


## Demo:
### Before:


https://github.com/user-attachments/assets/fd3b69fc-468a-4fd1-82c9-4f1aa83c6474




### After:


https://github.com/user-attachments/assets/0a6c70a9-0a4a-4657-9fe8-21988fff9e80



## Release Notes:

- Fixed play button appearing in gutter for unsaved buffers where
clicking it was a no-op.

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
antont and others added 5 commits April 22, 2026 17:51
Review feedback: derive_project_name has two gaps vs. `getProjectName`
in `src/spec-node/dockerCompose.ts`.

1. `docker_compose_manifest()` builds compose file paths by joining
   `self.config_directory` with each raw `dockerComposeFile` entry
   verbatim, so entries like "subdir/../docker-compose.yml" yield a
   `PathBuf` with unresolved `..`. `derive_project_name` compares
   `parent()` against `<workspace>/.devcontainer` and extracts
   `file_name()` from that raw parent — no normalization — so a file
   semantically under `.devcontainer` takes the wrong branch. Rust's
   `Path::file_name` returns `None` on a path ending in `..`, which
   collapses to `workspace_fallback` bare (not even the CLI's
   rule-4 `${workspace}_devcontainer`).

2. `is_missing_file_error` comment and doc mirror the CLI's narrow
   `ENOENT`/`EISDIR` swallow for the `.env` read, but the code catches
   `NotADirectory` (ENOTDIR) instead of `IsADirectory` (EISDIR). The
   prior unit test locked in the mismatch.

Failing output captured before fix:

    running 2 tests
    test …::derive_project_name_normalizes_compose_path_for_rule_4 ... FAILED
    test …::is_missing_file_error_only_accepts_notfound_and_isadirectory ... FAILED

    ---- derive_project_name_normalizes_compose_path_for_rule_4 ----
    assertion `left == right` failed
      left: "project"
     right: "project_devcontainer"

    ---- is_missing_file_error_only_accepts_notfound_and_isadirectory ----
    assertion failed: is_missing_file_error(&is_a_dir)

    test result: FAILED. 0 passed; 2 failed; 0 ignored.

GREEN lands in the next commit.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Fixes the two bugs pinned by 6d41917:

1. `derive_project_name` now normalizes the compose-file parent and the
   `<workspace>/.devcontainer` target path via `util::normalize_path`
   before comparing. `docker_compose_manifest()` joins
   `self.config_directory` with each raw `dockerComposeFile` entry
   verbatim, so paths can carry `..` components. Without normalization,
   `subdir/../docker-compose.yml` under `.devcontainer/` missed rule 4
   and `.devcontainer/../docker-compose.yml` had `None` from
   `file_name()` on the parent. The reference CLI's `getProjectName`
   does `path.resolve()` before its own branch, so this matches
   upstream.

2. `is_missing_file_error` now matches `IsADirectory` (EISDIR) instead
   of `NotADirectory` (ENOTDIR). The reference CLI's narrow `.env` swallow
   is `ENOENT || EISDIR`; the previous code swallowed `ENOENT || ENOTDIR`,
   which meant a `.env` that was actually a directory would propagate as
   a hard `FilesystemError` instead of falling through to rule 3–5.

Both RED tests from 6d41917 now pass. Full crate green: 87 passed.
Revert the pick_canonical_container stack. When multiple containers match
the identifying labels, propagate MultipleMatchingContainers (introduced in
the detection commit) untouched rather than trying to prefer one. The
mixed-version case — legacy and new containers coexisting — is a transient
edge that does not justify permanent code. Users with duplicate legacy
containers can clean them up once; the detection error surfaces the
mismatch with instructions.

Removes:
- pick_canonical_container method
- DockerConfigLabels.compose_project field and its serde rename
- Tests and helpers specific to the tiebreak

Per review on zed-industries#54302.
Replace serde_yaml_ng with yaml-rust2 for the single call site in
compose_fragment_declares_name. yaml-rust2 is already a transitive
workspace dependency (via tree-sitter-yaml and, until this commit,
serde_yaml_ng → unsafe-libyaml), so this is a net reduction of one
direct workspace dependency. The existing test covering block-style,
quoted-key, flow-style, and parse-failure inputs passes unchanged.

Per review on zed-industries#54302.
Testing out Niko's new SDK design

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
@antont
antont force-pushed the fix-compose-project-name-derivation branch from 2418589 to ca9e505 Compare April 22, 2026 15:03
antont and others added 24 commits April 22, 2026 18:17
Remove test_deserialize_single_json_object — it just tests that serde
deserializes a JSON object, which is serde's responsibility, not ours.
The remaining three tests still lock in the actual contract:
NDJSON is rejected, empty output is None, empty object is None.
…4511)

The `project_name` worktree setting was added in zed-industries#36713 to let users
override the name shown in the window title. Its description ("The
displayed name of this project. If left empty, the root directory name
will be displayed.") suggests broader coverage, and zed-industries#46440 reports the
reasonable expectation that it should also apply in the project
switcher. In practice the setting has only ever affected
`Workspace::update_window_title`, so everywhere else (recent projects,
the multi-worktree pane, ...) keeps falling back to the worktree root
name.

Rather than plumb the setting through each of those surfaces, I'm
removing it. Having a project-level setting control how your editor
displays the project has downsides. For example it means a checkout can
dictate UI in someone else's Zed. The natural home for a custom display
name is the workspace DB, set from the UI, which is what we should do if
we want this feature back.

If you want this back, the path forward is to store the display name in
`WorkspaceDb`, expose a UI affordance to edit it, and read it from
`update_window_title`, `recent_projects::get_recent_projects` /
`get_open_folders`, and any other places that currently derive a display
name from the worktree root.

Closes zed-industries#46440

Release Notes:

- Removed the `project_name` project setting. It only ever affected the
OS window title, and the expectation that it would show up in the
project switcher and elsewhere is better served by a future UI-driven,
per-workspace setting stored locally.
Adds documentation for the Parallel Agents feature.

## Changes

- **New page** `docs/src/ai/parallel-agents.md`: covers the Threads
Sidebar component, switching threads, the archive and search, importing
ACP threads, running multiple threads, multiple projects, worktree
isolation, and the default layout change
- **`docs/src/ai/overview.md`**: rewrites the Agentic editing section to
lead with the Threads Sidebar, adds Parallel Agents to the Getting
started links
- **`docs/src/ai/agent-panel.md`**: adds a cross-link to the Threads
Sidebar in Creating New Threads, removes the Navigating History section
(now covered in the Threads Sidebar docs)
- **`docs/src/SUMMARY.md`**: adds Parallel Agents between External
Agents and Inline Assistant

Release Notes:

- N/A

---------

Co-authored-by: Katie Geer <katie@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
## Summary

Closes zed-industries#53570

- `o` and `O` in normal mode were unconditionally copying the current
line's indentation into the new line, ignoring the `auto_indent` setting
entirely
- When `auto_indent: "none"` is set, new lines created by `o`/`O` now
start at column 0 as expected
- When `auto_indent` is `preserve_indent` or `syntax_aware`, behavior is
unchanged

The fix reads `language_settings_at` for the relevant row and splits
edits into two paths: `editor.edit()` (no autoindent) for `None`, and
`editor.edit_with_autoindent()` for everything else — mirroring the
approach already used by the non-vim `Newline` action.

## Test plan

- Added `test_o_auto_indent_none`: verifies `o`/`O` produce column-0
lines with `auto_indent: "none"`, including edge cases (first line,
empty line)
- Added `test_o_preserve_indent`: verifies `o`/`O` copy the current
line's indentation with `auto_indent: "preserve_indent"` (regression
guard)
- Existing neovim-backed tests (`test_o`, `test_insert_line_above`,
`test_o_comment`) continue to pass

Release Notes:

- Fixed vim `o`/`O` commands ignoring the `auto_indent: "none"` setting,
causing new lines to inherit indentation instead of starting at column 0
…gex-special characters (zed-industries#54422)

Closes zed-industries#54331
Updates zed-industries#50848

Release Notes:

- Fixed hang in replace all when the query contained non-ASCII text and
regex-special characters
…ndustries#54356)

Closes zed-industries#49581

Adds a `line_ending` language setting that controls how line endings are
handled for new files and during format/save:

- `detect` (default) — detects existing line endings; new files use the
platform default
- `prefer_lf` / `prefer_crlf` — sets LF or CRLF for new files and files
with no existing convention, while preserving existing files
- `enforce_lf` / `enforce_crlf` — normalizes all line endings to LF or
CRLF on every format/save

The setting can be configured globally, per-language, or via
`.editorconfig`'s `end_of_line` property (which maps to `enforce_lf` /
`enforce_crlf`).

Release Notes:

- Added `line_ending` setting to control how line endings are handled
for new files and normalized on save.
- Added support for `.editorconfig` `end_of_line` property to enforce
line endings.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
…elf (zed-industries#54204)

Previously, we would show these checkboxes whenever hovering anywhere in
the `entries` group, which covers all headers and status entries. This
seems excessive, and also has a problem that the header checkboxes
disappear when the mouse moves over a non-header (status entry)
checkbox, presumably because those have `stop_propagation`. Now, we only
show the checkbox for a header when that specific header is hovered.

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
Self-Review Checklist:

Closes zed-industries#53863

Updates zed-industries#53920
Updates zed-industries#51949
Updates zed-industries#45166

Release Notes:

- Updated auto_save_on_focus_change to handle modals better.
…ches (zed-industries#54519)

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 zed-industries#54517

Release Notes:

- Fixed Command Palette behavior where footer actions could still route
to a fallback hidden command when search returned no matches.
Previously hitting `Publish` in the git panel would silently fail with
no error message if the git repo was new or didn't have a remote.

Now, when hitting `Publish` or attempting to push when there is no
remote using keyboard shortcuts, or using `Push To` or force push
options, an error message will be displayed.

<img width="1135" height="522" alt="Screenshot 2026-04-22 at 10 02
26 AM"
src="https://github.com/user-attachments/assets/93c5e7ee-371e-4c2c-961b-42501cbd7119"
/>

<img width="1135" height="522" alt="Screenshot 2026-04-22 at 10 02
36 AM"
src="https://github.com/user-attachments/assets/a923e5f2-4099-45b5-8fe2-eb78f4fc9f10"
/>


Self-Review Checklist:

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

Release Notes:

- Fixed handling of `git push` when there is no remote available to push
to
Move `..`-resolution from `derive_project_name` to `docker_compose_manifest`
so every downstream consumer of `DockerComposeResources.files` (fragment
reads, project-name derivation, `docker compose -f` invocations) sees
resolved paths. Per Kyle's review on zed-industries#54302 (discussion_r3125767714).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
It's currently not valid to limit the syntax highlighting cursor in this
way, because it prevents us from recognizing important patterns like
`(function_item name:(identifier) @function` if the function exceeds the
context length, which is common. We'll need to think harder about
whether there's a different solution the problem of slow queries in the
presence of large parse errors.

Reverts zed-industries#52674
…#49106)

Release Notes:

- Fixed heredoc commands failing with "syntax error: unexpected end of
file" in AI Agent shell execution

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Spelling flagged by upstream CI's typos check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…abs open (zed-industries#51434)

Release Notes:

- helix: Fix some commands that you might want use when you have no
panes open, like project or symbol search.

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Self-Review Checklist:

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

Release Notes:

- N/A
Closes zed-industries#52629

## Overview

Adds a generic editor-owned navigation overlay primitive for rendering
target ranges, anchored labels, and fade ranges. This gives [Helix amp
jump](zed-industries#43733), [Beam
Jump](zed-industries#45387), and future
jump-style features (like [this
one](zed-industries#14801)) a shared
editor abstraction for overlay layout and paint instead of
feature-specific render paths.


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

Release Notes:

- Fixed an issue where pressing `Escape` in the search bar did not dismiss it when using the Helix keymap, while it worked correctly in Vim mode.

Co-authored-by: buildingvibes <buildingvibes@users.noreply.github.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
…ies#54532)

Adds a link to the Tasks section of the docs from the Worktree Isolation
section in parallel-agents.md

Release Notes:

- N/A
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.