Commit Graph
3227 Commits
Author SHA1 Message Date
Lukas Wirth a6a2cd66b0 language_core: Remove lsp-types dependency (#61041)
Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-15 10:46:01 +00:00
Xin Zhao 272d4f1cc2 project: Persist workspace diagnostics when closing buffer (#59875)
# Objective

Closes #50739

Many language servers have settings for their diagnostic mode, typically
supporting either "single file" mode or "workspace" mode.

In single file mode, the language server only generates diagnostics for
files that the user has open. When a file is closed, those diagnostics
are cleared. This is the behavior currently implemented in Zed.

However, when a language server runs in workspace mode, we should retain
all diagnostics regardless of whether the corresponding file is open or
closed. As reported in #50739, Zed currently discards these diagnostics
when a buffer is closed, just like in single file mode.

When a buffer is completely closed, Zed triggers a diagnostics update to
perform cleanup:

https://github.com/zed-industries/zed/blob/6e8b0ae150b6140a398a87a3eb1cd4dd1568c504/crates/project/src/lsp_store.rs#L4747-L4773
and the Pulled diagnostics are all cleaned, that's why when closing a
buffer, the diagnostic summary disappeared. This process aggressively
clears all `Pulled` diagnostics, causing the diagnostic summary for the
closed file to disappear.

## Solution

Filter the target language servers when updating diagnostics on buffer
close. If a language server has workspace diagnostics enabled, we skip
clearing its diagnostics.

## Testing

Added two new integration tests in
`crates/project/tests/integration/project_tests.rs`:
1.
`test_diagnostic_summaries_cleared_on_buffer_close_without_workspace_diagnostics`:
Verifies that diagnostics are cleared on buffer close when workspace
diagnostics is disabled.
2.
`test_diagnostic_summaries_retained_on_buffer_close_with_workspace_diagnostics`:
Verifies that diagnostics are retained when workspace diagnostics are
enabled. (This test fails on the current `main` branch).

I have also verified this functionality locally. Both local and remote
development environments work as expected.

## Self-Review Checklist:

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

## Showcase

<details>
  <summary>Click to view showcase</summary>

My super cool demos here

</details>

---

Release Notes:

- Fixed workspace diagnostics being cleared when closing a buffer.
2026-07-15 08:43:47 +00:00
Lukas Wirth 6b6393fb0b Split out RelPath into a separate crate (#61029)
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 ...
2026-07-15 08:33:25 +00:00
Ben Kunkle d224ea86e8 Add a bespoke LSP request path for edit prediction context (#60947)
Closes EP-193

Edit prediction context collection previously reused the editor
goto-definition / goto-type-definition path, which resolves every LSP
result into a `LocationLink` — opening a buffer per target (worktree
creation, buffer registration, anchor conversion) before edit prediction
gets a chance to filter. On remote projects the host additionally
created a peer-visible buffer per link and the client waited on each
one.

This adds a bespoke request path that returns raw results first and only
does the expensive work for results that survive filtering:

- New `EditPredictionDefinition { path: ProjectPath, range:
Range<Unclipped<PointUtf16>> }` boundary type. LSP wire types never
leave `lsp_command.rs`; the workspace-only filter and URI→`ProjectPath`
resolution happen while normalizing the LSP response, before any buffer
exists, so the type encodes the workspace-only invariant.
- New `GetEditPredictionDefinitions` /
`GetEditPredictionTypeDefinitions` LSP commands and proto messages.
Responses carry only path + UTF-16 range — the host never calls
`create_buffer_for_peer` and the client never waits on remote buffers.
- One public API: `Project::edit_prediction_definitions(buffer,
position, include_type_definitions, cx)` fires both LSP requests
concurrently and returns a merged, deduped list ("not capable" = empty).
The definition/type-definition split was never used downstream, so
`CacheEntry` now holds a single list and the fetch pipeline runs one
task per identifier.
- `edit_prediction_context` dedupes raw results before opening buffers;
survivors open via `project.open_buffer(ProjectPath)` (skipping the
invisible-worktree/yarn machinery of `open_local_buffer_via_lsp`, and
working identically on remote projects), then clip → anchor →
`MAX_TARGET_LEN`.
- Removes the `workspace_only` flag from `GetDefinitions` /
`GetTypeDefinitions`: edit prediction was its only user. The editor path
always sent `false`, which proto3 doesn't encode, so normal
goto-definition requests are wire-identical; old peers still sending
`true` get unfiltered results (graceful degradation). The proto field
numbers are `reserved`.

Tested with a local test proving filtering precedes buffer opening (an
out-of-workspace target never spawns a worktree, an oversized target is
excluded from related files) and a collab test proving the remote
round-trip returns correct paths/ranges without opening buffers on the
client.

Release Notes:

- N/A
2026-07-15 01:54:27 +00:00
Mikayla Maki b4018f4c7e Open gitignored subdirectories as their own workspace (#60918)
# Objective

Let's git ignored directories be opened as their own project


## Solution

- Add an "ignored dir" carve out when checking project collision

## Testing

- Added tests

## 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
- [-] Performance impact has been considered and is acceptable

---

Release Notes:

-
2026-07-14 15:34:30 +00:00
Ruslan SemaginandDanilo Leal b220d078bf Show tag names in git blame tooltips (#60757)
Fetch tag names for commits included in blame data and pass them through
the blame rendering path. Render tag names as chips in the blame hover
tooltip and expanded blame popover. Tag lookup is best-effort, so blame
still renders if tag lookup fails.

> Note: Tag names are currently only fetched for local repositories. For
remote projects (SSH) and collab sessions, blame data travels over the
`BlameBufferResponse` proto message, which doesn't carry tag names yet.

  ## Testing

- `cargo test -p git
test_parse_tag_names_for_lightweight_and_annotated_tags`
  - `cargo check -p git_ui`
  - `cargo check -p editor`
  - `cargo check -p project`

  Manual testing:
  - Opened `git: blame` on a file with a tagged commit.
- Verified tag chips are shown in the blame hover tooltip and expanded
popover.

  ## Self-Review Checklist:

  - [x] I've reviewed my own diff for quality, security, and reliability
  - [x] Unsafe blocks (if any) have justifying comments
- [x] The content adheres to Zed's UI standards
([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
and [icon]

(https://github.com/zed-industries/zed/blob/main/crates/icons/README.md)
guidelines)
  - [x] Tests cover the new/changed behavior
  - [x] Performance impact has been considered and is acceptable

  ## Showcase

Before:
<img width="1655" height="660" alt="before"
src="https://github.com/user-attachments/assets/dbefd729-f8df-48a9-8249-83c93518fe76"
/>

After:
<img width="1655" height="660" alt="after"
src="https://github.com/user-attachments/assets/2c1097de-b268-45d9-9d13-0f3e06058603"
/>

---

Release Notes:

- Git: Made tags visible in Git blame tooltips.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-07-14 01:21:38 +00:00
Apoorva VermaandKirill Bulatov f7e2380479 project: Report formatter failures in the status bar again (#60839)
set a formatter that fails (`"formatter": {"external": {"command":
"false"}}`), save, and you get nothing. it just goes to the log, the
"Formatting failed" indicator never shows.

#51605 made the formatter loop log-and-continue instead of bailing (so
unrelated edits don't get reverted, #51490). downside was the pipeline
always returned Ok after that, so the failure flag the indicator reads
always got wiped. this brings back failures from formatters you actually
configured. auto ones stay quiet when they're not around, so no prettier
installed = still a no-op.

only explicit failures show up, bit narrower than before #51605. can
widen it to auto ones too if you want, one line.

Fixes #59988.

Release Notes:

- Fixed formatter failures not showing the "Formatting failed" status
bar indicator

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-13 20:24:53 +00:00
Smit Barmase b340949cb6 git_ui: Fix remote branches missing from branch diff base picker (#60765)
The branch picker collapses remote branches that are tracked by a local
branch (e.g. `origin/main` when local `main` tracks it). That makes
sense for checkout, where the remote ref is redundant, but it was also
applied to the branch diff base picker, where `main` and `origin/main`
can point to different commits. As a result, once you switched the diff
base from `origin/main` to `main`, there was no way to switch back.

The tracked-remote collapsing is now only applied in checkout mode (no
changed here). The select (diff base) picker lists both local branches
and their remote upstreams.

Release Notes:

- Fixed remote branches (e.g. `origin/main`) not appearing in the branch
diff base picker, making it impossible to switch back after changing the
base to another branch.
2026-07-13 15:21:35 +00:00
Tyler BenfieldandSmit Barmase 8e863013b4 Fix remote worktree picker hides "Create from origin/main" option (#59134)
This passes the `include_remote_name` flag through the remote
`GetDefaultBranch` RPC instead of dropping it at the client/host
boundary. That lets remote repositories resolve default branches as
`origin/main` when needed, so worktree creation uses a valid remote
branch name instead of falling back to `main`.

Self-Review Checklist:

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

Closes #59121

Release Notes:

- Fixed remote worktree creation from the default branch when the
default branch requires its remote name.

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-07-10 12:11:57 +00:00
David WuandLukas Wirth fb4885a55e Open non-writeable files in Capability::Read mode (#57202)
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 #57174

Release Notes:

- Open non-writeable files in Capability::Read mode

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-07-10 09:50:19 +00:00
b0fa17419b Fix MCP servers in multi root workspaces (#52849)
### Closes #51951

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

#### Note : Reopens previous work from closed PR
https://github.com/zed-industries/zed/pull/52161 (fork was deleted)

## Video 

[Screencast from 2026-03-22
23-26-06.webm](https://github.com/user-attachments/assets/ab68e47a-7e74-4f1e-991d-8ca4fed7952c)


## Release Notes:

- Fixed MCP servers from `.zed/settings.json` not being discovered when
multiple project folders are open in a workspace.

---------

Co-authored-by: Bennet Bo Fenner <bennetbo@gmx.de>
Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
2026-07-10 09:13:45 +00:00
Keith Hall bfd21aa8dc search: Bump fancy-regex dependency and enable CRLF mode (#55471)
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 #43396

Release Notes:

- Project search now supports CRLF line endings correctly, as well as
other regex features like subroutine calls
2026-07-08 16:56:45 +00:00
G36maidandKirill Bulatov 2eeb3e9f47 Add support for format_on_save only changed lines (#49964)
## Summary

Introduces `format_on_save` variants that format only modified lines,
limiting formatting to lines changed since the last commit. This
prevents massive diffs when editing legacy codebases. Aligns with VS
Code's `editor.formatOnSaveMode` naming:

- `"modifications"` — formats only git-diffed lines. Requires source
control; skips formatting if no diff is available.
- `"modifications_if_available"` — formats only git-diffed lines,
falling back to full-file formatting for untracked files, when source
control is unavailable, or when the LSP does not support range
formatting.

Also supports importing equivalent VS Code settings
(`formatOnSaveMode`).

This PR uses the range-based whitespace/newline infrastructure from the
dependency PR above.

## Changes


<details>
<summary><b>New settings, modified ranges computation, VS Code
import</b></summary>

### New settings (`language.rs`, `default.json`, `all-settings.md`)

Two new `FormatOnSave` variants: `Modifications` and
`ModificationsIfAvailable`.

### Modified ranges computation (`items.rs`)

- `compute_format_decision()` — reads `format_on_save` setting across
all buffers, determines whether to use ranged formatting (`Ranges`),
full formatting (`Full`), or skip (`Skip`).
- `compute_modified_ranges()` — extracts modified line ranges from git
diff hunks via `BufferDiffSnapshot`.
- `is_empty_range()` — helper to detect deletion-only hunks that produce
no formatable content.

The `save()` method calls `compute_format_decision()` and dispatches
accordingly.

### Modifications mode in `lsp_store.rs`

- Adds `FormatOnSave::Modifications |
FormatOnSave::ModificationsIfAvailable` to the formatter selection match
arm.
- `ModificationsIfAvailable` falls back to full-file formatting when
ranged formatting produces no results.

### VS Code settings import (`vscode_import.rs`, `settings_store.rs`)

Imports `editor.formatOnSaveMode` mapping:
- `"modifications"` → `FormatOnSave::Modifications`
- `"modificationsIfAvailable"` →
`FormatOnSave::ModificationsIfAvailable`
- `"file"` → `FormatOnSave::On`

</details>

## Tests

- `test_modifications_format_on_save` — basic modifications mode
formatting with dirty buffer
- `test_modifications_format_no_changes` — clean buffer triggers no
formatting
- `test_modifications_format_lsp_no_range_support` — LSP without range
formatting skips entirely for `Modifications`
- `test_modifications_format_lsp_returns_empty_edits` — empty edits
handled gracefully
- `test_modifications_format_multiple_hunks` — two non-adjacent edits
produce two separate range formatting requests

---

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 #16509
Depends on #53942

Release Notes:

- Added `modifications` and `modifications_if_available` options to
`format_on_save`, which format only git-changed lines instead of the
entire file
- When using modifications mode, `remove_trailing_whitespace_on_save`
and `ensure_final_newline_on_save` are also scoped to changed lines,
preventing unwanted diff jitter in legacy codebases
- Added support for importing VS Code's `editor.formatOnSaveMode`
setting

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-08 16:53:11 +00:00
Ibrahim Khan c09d59120c project: Fix content swap when an LSP rename also renames the file (#59104)
A "rename symbol" whose workspace edit also renames the file (a
`TextDocumentEdit` followed by a `RenameFile` resource operation) only
applied the text edit to the in-memory buffer. The on-disk file still
held the pre-edit content, so the blind `fs.rename` moved stale bytes to
the new path while the edited buffer was stranded at the old path,
swapping the two files' contents.

This persists a dirty buffer for the rename source before renaming, so
the new file receives the edited content and the now-clean buffer can't
be saved back to the old path.

Self-Review Checklist:

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

Closes #59077

Release Notes:

- Fixed a symbol rename that also renames the file swapping the contents
of the old and new files
2026-07-08 12:21:10 +00:00
RainandKirill Bulatov 9efc6f5e16 Fix should_log_lsp_request_failure logic inversion (#57554)
Was trying to debug an r-a issue and ran into this.

Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliabilityx
- [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 ...

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-08 12:08:36 +00:00
Lukas Geiger 601690391b git: Load buffer git diff bases with a single batched git process (#59357)
# Objective

Whenever the git repository state is updated on disk (e.g., via staging,
committing, branch switching, or stashing), `reload_buffer_diff_bases`
is scheduled to reload the diff for all active buffers. This causes 2
git processes to be spawned for each open file which can become
noticeable when many files are open

https://github.com/zed-industries/zed/blob/b2617baa21a83dfcbd8361e285bb2eba84e294ec/crates/project/src/git_store.rs#L5179

## Solution

This PR introduces `load_revisions` which uses a single `git cat-file
--batch` command to compute the diff for all files in the same git
process. This prevents the need to sequentially schedule 2 git
subprocesses per open buffer.

I also changed `load_index_text` and `load_commited_text` to rely on
`load_revisions` which simplifies the code.

## Testing

I added a unittest and manually verified that Zed now only runs a single
`git cat-file --batch` command instead of 2 `git show` processes per
open buffer.
On macOS I viewed the currently running git processes using:
```shell
sudo eslogger exec | jq --unbuffered -r '
    select(.event.exec?.target?.executable?.path? | strings | contains("git")) |
    (.event.exec?.args? // []) | join(" ")
  '
```

## Self-Review Checklist:

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

/cc @Veykril

Release Notes:

- Reduced number of git processes for calculating diff of open buffers
when the repo state changes on disk
2026-07-07 14:02:31 +00:00
Lukas Wirth c99df2bea6 project: Create LSP file watcher on the background (#60530)
Release Notes:

- N/A or Added/Fixed/Improved ...
2026-07-07 11:48:14 +00:00
Smit Barmase d1da3983ec project: Fix ref-match rust completions dropping the leading & (#60521)
Closes #56973, Follow-up for
https://github.com/zed-industries/zed/pull/56976

When a completion's `additionalTextEdits` contained a zero-width
insertion touching the edge of the primary edit, the overlap check
treated it as overlapping and silently skipped it. This broke
rust-analyzer's ref-match completions (`&foo`), which deliver the `&` as
a zero-width additional edit at the primary edit's start (#56973). The
same root cause previously broke auto-imports at the very start of a
file (#26136), which was worked around in #37746 with a special case for
edits at position (0, 0).

This PR replaces that special case with a general rule: a zero-width
additional edit only overlaps the primary edit when it falls strictly
inside it. i.e. touching the boundary is fine.

This one check handles both the file-start auto-import case and the `&`
ref-match case, so the (0, 0) workaround from #37746 is removed.
Non-insertion edits still go through the original overlap check from
#1871.

Added three regression tests:
- the file-start auto-import (#26136)
-  the `&` insertion at the primary edit's start (#56973)
- overlapping edits being skipped while non-overlapping ones apply
(general skip case)

Release Notes:

- Fixed rust-analyzer completions like `&some_var` inserting only the
variable name and dropping the leading `&` when accepted.
2026-07-07 07:49:53 +00:00
48192372a0 Git partially staged changes (#46541)
This PR explores the addition of a new feature and UI to improve
visibility into partially staged commits.

Currently, the Git panel shows tracked and untracked changes, but it
does not clearly distinguish between staged and unstaged changes.

As a result, it’s difficult to quickly see which changes are not staged
in the current UI. Both staged and unstaged changes are combined into
the `Uncommitted Changes` multibuffer. This developer experience differs
from other editors, most notably VS Code; which presents separate Staged
Changes and Changes lists.

### Staged and unstaged diffs in multibuffers

This PR introduces an alternative UI for unstaged changes that aligns
with the overall Zed experience. Instead of showing changes on a
per-file basis, staged and unstaged diffs are each displayed in their
own multibuffers, similar to how `Uncommitted Changes` currently works.

For example the following screenshot shows the current `Uncommitted
Changes` on the left, the `Staged Changes` in the middle and the
`Unstaged Changes` buffer on the right for comparison

<img width="1408" height="859"
src="https://github.com/user-attachments/assets/aa709f7a-041d-4cb1-95d6-84c0f5fff688"
/>

### Indicators/interactions

The new multibuffers can be opened in two ways:

1. Via a new `U` chip, which appears when a file has unstaged changes
2. Via new menu options

(See screenshots below for both interaction paths.)


<table>
  <tr>
    <td style="text-align: center; vertical-align: top;">
      <p>via the chip</p>
      <img
        height="400"

src="https://github.com/user-attachments/assets/3ef69f02-b787-499c-959a-25f50b3728e8"
        alt="Via the chip"
      />
    </td>
    <td style="text-align: center; vertical-align: top;">
      <p>via the menu</p>
      <img
        height="400"

src="https://github.com/user-attachments/assets/f5be8b6d-ccdc-4420-bd29-75570b558016"
        alt="Via the menu"
      />
    </td>
  </tr>
</table>

### Design goals
- minimally intrusive UI changes (small new badge and menu items)
- adhere by Zed'ism (use multibuffer where possible)
- avoid disabling any current interactions (Uncommitted Changes ui is
unchanged)
- avoid introducing an app level view mode (no new settings needed)

### Experience goals
- make it easy to see what changes are not staged
- make it easy to see that a file has unstaged changes (avoid developers
accidently leaving out changes in a commit; a personal issue that I have
when using Zed)
- elegantly handle large file's unstaged changes (follows the same
collapse and expanding seen in `Uncommitted Changes`)

### How to try

- Clone the repo and run `cargo run`
- Make a change to a file and stage it
- Make another change to the file (the `U` indicator will appear)
- Click the `U` to see the unstaged view

### Open questions/rough edges
- [ ] determine if this user experience is useful for others
- [ ] ensure all interactions work as expected (response to all update
cases)

In general I'm really interested in hearing the community's feedback
about this interface, more than happy to make any changes or explore a
different solution!

### Related issue:
- https://github.com/zed-industries/zed/pull/36646
- https://github.com/zed-industries/zed/issues/26560

Release Notes:

- Support partially staged commit multibuffers via a staged and unstaged
changes view.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cole Miller <cole@zed.dev>
2026-07-07 06:55:29 +00:00
David Alecrim 1aa80354a4 Fix text finder crash from unbounded memory use (#60377)
- Fixes #60238.
- The text finder could spike memory into the tens of gigabytes and
crash the app. The finder was copying the full matched line into every
match it kept, so memory grew with the number of matches times the size
of each line. Enough matches carrying enough text and the process runs
out of memory.

## Solution

- Stop storing line text on matches. Each match now keeps only its
position and column, and the text shown in a row is built lazily for the
visible rows, using a bounded slice around the match rather than the
whole line. Line boundaries come from the buffer's line index instead of
re-scanning the content per match.
- Cap the number of matches the finder builds while streaming results,
using the same ceiling project search already applies. This keeps the
finder from ever assembling an unbounded match list on the UI thread.
- Behavior is unchanged: every occurrence is still its own row, jumping
to a match lands on the exact line and column, and the rendered text and
highlighting look the same. The finder just no longer holds text
proportional to the match count.

## Testing
- Added tests covering the new behavior: the match count is capped while
streaming, every occurrence below the ceiling still becomes its own
match at the correct line and column, and the rendered slice around a
match stays bounded on a huge line while still covering a whole short
line.
- Verified by hand with the reproduction from the issue. The screenshot
below shows the memory usage and the matching against the issue data:
<img width="1277" height="1053" alt="Screenshot 2026-07-03 at 17 43 11"
src="https://github.com/user-attachments/assets/71c0aa3b-2423-427d-91ba-792951d9ba31"
/>

## Self-Review Checklist:

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

---

Release Notes:

- Fixed a crash and high memory usage in the text finder.
2026-07-06 15:21:32 +00:00
Lukas Geigeranddino e3f01a1c88 git: Do not recompute git_access on every file change (#59521)
# Objective

As mentioned in #59514, the git panel currently runs a full `git status`
for checking whether `git` has access to the repository. This was
introduced in #43693 and currently runs on every file save which is
problematic for large repos where `git status` runs a lot of
computation.

## Solution

This PR caches the `git_access` on the git panel such that we don't need
re-check for git access on every file save.

## Testing

I manually verified that the git panel doesn't trigger anymore
unnecessary git status commands.

**main:**
```
2026-06-18T00:04:24+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967643
2026-06-18T00:04:24+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967643
2026-06-18T00:04:24+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967643
2026-06-18T00:04:24+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967643
2026-06-18T00:04:24+01:00 DEBUG [project.format.local] formatting buffer '"/Users/lgeiger/code/zed/CONTRIBUTING.md"'
2026-06-18T00:04:24+01:00 DEBUG [project.format.local] no changes made while formatting
2026-06-18T00:04:24+01:00 DEBUG [git::repository] Checking for git status in ["CONTRIBUTING.md"]
2026-06-18T00:04:25+01:00 DEBUG [git::repository] Checking for git status in []
```
```
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z -- CONTRIBUTING.md
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager diff --numstat --no-renames HEAD -- CONTRIBUTING.md
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager config --get commit.template
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z --
```

**This PR:**
```
2026-06-18T02:47:54+01:00 DEBUG [project::git_store] start recalculating diffs for buffer 4294967656
2026-06-18T02:47:54+01:00 DEBUG [project::git_store] finished recalculating diffs for buffer 4294967656
2026-06-18T02:47:55+01:00 DEBUG [project.format.local] formatting buffer '"/Users/lgeiger/code/zed/CONTRIBUTING.md"'
2026-06-18T02:47:55+01:00 DEBUG [project.format.local] no changes made while formatting
2026-06-18T02:47:55+01:00 DEBUG [git::repository] Checking for git status in ["CONTRIBUTING.md"]
```
```
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager diff --numstat --no-renames HEAD -- CONTRIBUTING.md
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager status --porcelain=v1 --untracked-files=all --no-renames -z -- CONTRIBUTING.md
/opt/homebrew/bin/git -c core.fsmonitor=false -c log.showSignature=false --no-optional-locks --no-pager config --get commit.template
```


## Self-Review Checklist:

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

/cc @dinocosta


---

Release Notes:

- Improved Git Panel performance by no longer re-checking repository
access on every file change

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-07-03 20:43:32 +00:00
bgfraserandTom Houlé 74fcda8b23 Initiate MCP OAuth flow on post-initialize 401 responses (#60236)
MCP servers may accept `initialize` unauthenticated but return `401`
with a `WWW-Authenticate` challenge only on a later request such as
`tools/list` or `tools/call`. Previously Zed only started the Auth flow
when `initialize` itself was challenged, so these servers failed
opaquely and stayed stuck in `Running` with a dead client.

`ContextServerStore` now handles `TransportError::AuthRequired` returned
from any request, not just startup: it runs Auth discovery and
transitions the server into `AuthRequired` so the UI offers to
authenticate. The discovery logic is shared with the startup path, and
the tool/prompt request sites route their errors through it.

Release Notes:

- Fixed MCP servers that require auth only on tool calls (not on
`initialize`) failing to prompt for authentication.

---------

Co-authored-by: Tom Houlé <tom@tomhoule.com>
2026-07-03 18:24:54 +00:00
Anant GoelandAnthony Eid f023a7e4a3 Fix worktree grouping for bare checkouts (#59968)
Summary

- Track whether a worktree root is itself a linked Git worktree.
- Use that metadata when computing project group keys so bare checkout
worktrees group under the repository identity path.
- Propagate the metadata through remote worktree protocols and add
local/remote regression coverage.

Background

Bare checkout layouts can place linked worktrees under the repository
identity directory, e.g. `/monty/.bare` with worktrees like
`/monty/feature-a`. We were treating those linked worktree paths as
separate project identities, which caused the sidebar to move agent
threads under the active worktree instead of the shared repository
group.
We also exclude adding this to collab intentionally, we can open a
different PR for that if we need to.

Closes #59910
Closes AI-431

Test Plan

- `cargo fmt --package project --package worktree --package
remote_server --package workspace --package collab --package proto`
- `git --no-pager diff --check`
- `cargo test -p project test_project_group_key -- --nocapture`
- `cargo test -p remote_server test_remote_root_repo_common_dir --
--nocapture`
- `cargo test -p worktree remote_worktree -- --nocapture`
- `cargo test -p workspace
test_remote_project_root_dir_changes_update_groups -- --nocapture`
- `cargo check -p collab`

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

Release Notes:

- Fixed agent thread/sidebar grouping for Git worktrees backed by bare
checkouts.

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
2026-07-02 18:14:11 +00:00
mertkanakkocandPiotr Osiewicz c3b66b9c5c Project/use line hint for search (#58871)
Self-Review Checklist:

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

This PR makes two changes:

1. detect() now returns the line number of the first match instead of
just a boolean.
2. This line number (line_hint) is threaded through the pipeline and
passed as a subrange to query.search in full buffer scan, so the full
buffer scan starts from where the first match was already found instead
of the beginning of the file.
 
 ## Scope

  - This optimization only applies to **local search** (not remote).
- It is only effective for **single-line text and single-line regex**
queries. For multiline queries, `detect()` returns `line_hint = 0`, so
the full buffer is scanned from the beginning as before.
- It does not apply to already-open buffers, which always receive
`line_hint = 0`.
  
  ## Test
i tried to search the word "typeably" in the file
"pkgs/development/haskell-modules/hackage-packages.nix" of the repo
[nixpkgs](https://github.com/NixOS/nixpkgs) given in the comment:
[comment](https://github.com/zed-industries/zed/issues/38799#issuecomment-4088491295).
Result seems promising:
 
**with line_hint: 
search: 45.21ms** 

**without line_hint:
search: 508.05ms** 

I measured the time within the function: "handle_find_all_matches"

## Assumption

The core assumption is: if the search query is long enough (after 4 or 5
chars), the probability of finding multiple matches in a single file is
low. In that case, re-scanning the content before line_hint is
unnecessary — detect() function already confirmed there is no match
there.
 
Changes maybe can make an improvement on issues #38799 and #58905

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
2026-07-02 09:46:33 +00:00
Remco Smits cf7248308b git_store: Avoid redundant work in worktree git repository update (#60205)
## Objective

While profiling https://github.com/zed-industries/zed/issues/60102 I
noticed `GitStore::update_repositories_from_worktree` does unneeded
work. It fires on every `WorktreeUpdatedGitRepositories` event, which
under filesystem pressure (`rescan: user dropped`) repeats roughly once
per second and can fire more frequently in a large monorepo with many
repositories, since the redundant work scales with the number of
repositories.

## Solution

In `crates/project/src/git_store.rs`:

- Drop the per-iteration `Arc<Path>` clone in the repo lookup; compare
the borrowed reference instead.
- Hoist the `is_trusted` (`can_trust`) computation out of the loop since
it only depends on `worktree_id`.

No behavior change is intended; this is purely reducing redundant work
per event.

## Notes

The *frequency* of these events originates upstream in
`LocalWorktree::changed_repos` (`crates/worktree/src/worktree.rs`),
which re-emits an `UpdatedGitRepository` whenever `git_dir_scan_id`
changes on a full rescan. That path is intentionally left untouched here
since it involves scan semantics; this PR only addresses the redundant
work on the consumer side.

## Self-Review Checklist:

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

---

Release Notes:

- N/A
2026-07-02 09:08:18 +00:00
G36maidandKirill Bulatov 2a3f40aba8 Add range-based whitespace and newline removal to buffer formatting (#53942)
## Summary

When formatting specific ranges (e.g. via Format Selections), trailing
whitespace removal and final newline enforcement currently operate on
the entire file. This PR makes these operations range-aware, so they
only affect lines within the target ranges.

As noted in #16509, users want `remove_trailing_whitespace_on_save` and
`ensure_final_newline_on_save` to suppress jitter by only touching
changed lines. This PR provides the foundational infrastructure for that
— range-based whitespace and newline operations — which a follow-up PR
will wire into the `format_on_save` modifications mode.

## Changes

- Added `remove_trailing_whitespace_in_ranges` and
`ensure_final_newline_in_range` to `Buffer`
- When a `FormattableBuffer` has ranges set, whitespace and newline
operations now use the range-based variants
- `format_ranges_via_lsp` returns `Ok(None)` instead of an error when
the LSP doesn't support range formatting
- Extracted `anchor_ranges_to_row_ranges` helper to deduplicate
conversion logic

<details><summary>Tests (4)</summary>

- `test_trailing_whitespace_in_ranges` — only modified lines have
whitespace removed
- `test_trailing_whitespace_empty_ranges` — empty ranges → no changes
- `test_final_newline_modified_last_line` — newline added when last line
is in range
- `test_final_newline_unmodified_last_line` — newline not added when
last line is outside range

</details>

---

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 Format Selection to scope trailing whitespace removal and
final newline enforcement to the selected range instead of the entire
file
- Improved handling of LSP servers that do not support range formatting
by gracefully skipping instead of producing an error

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-07-01 17:36:36 +00:00
Bennet Bo Fenner 03903ea28f cli: Always open new window when cli_default_open_behavior=new_window (#59415)
This makes sure that the behaviour of the CLI matches that of the UI.
In Zed itself we always open a new window (e.g. when clicking on Open
Project in new window in the recent projects picker), but in the CLI we
where re-using existing windows even when specifying
"cli_default_open_behavior": "new_window".
This caused confusion, so this PR ensures that we always open a new
window, even if that folder is already open. We still focus the active
window in the case where the path is a subpath of a project that is
already open.

Can be tested with

```
cd crates/cli
cargo run -- --zed ../../target/debug/zed somefolder
```

Release Notes:

- cli: Ensure `zed somefolder` always opens a new window, even when
`cli_default_open_behavior` is set to `new_window` and the project is
already open
2026-06-30 20:10:06 +00:00
Ben BrandtandSmit Barmase 268186cd9a acp: Support boolean ACP config options (#59698)
Still behind a feature flag until the RFD is completed.

Release Notes:

- N/A

---------

Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
2026-06-30 10:12:25 +00:00
Davit Koshkeli 0acb09e5a3 git: Allow showing inline blame in the status bar (#59696)
# Add status bar location for inline git blame

## Objective
- Closes #12133 by implementing the VS Code-like behavior for status bar
git blame


## Solution

Adds a VS Code–style option to render the current-line git blame in the
status bar instead of inline at the cursor.

Whats new 
- A new location setting: Under the inline_blame configuration, you can
now choose between two options:
- `inline` (Default) — Keeps things exactly as they are, showing the
blame details at the end of your current line.
  - `status_bar` — Moves the blame info down to the bottom status bar.
- The Status Bar Item: When you choose the status bar option, a clean
new button appears at the bottom left of your window. It features a Git
icon, the author's name, how long ago the change was made, and the
commit summary
  - Behaves as it does before, but displayed at a different location
- Clicking the status bar item will instantly open up the full Git
commit details like at vscode
- Settings UI:
- The "Location" control is now a `DynamicItem` nested under "Enabled",
so it only appears when inline blame is enabled.
  - Registers a dropdown renderer for `InlineBlameLocation`.
- Updates `all-settings.md` and `visual-customization.md` for the new
option.

## Testing

- Manually tested both modes by toggling `git.inline_blame.location`
between `inline` and `status_bar`:
  - `inline` keeps the existing behavior unchanged.
- `status_bar` shows the blame for the focused line in the status bar,
hides the inline blame, updates on cursor movement, clears when no
editor is focused, and opens the blame commit on click.
- Verified the settings UI shows the "Location" dropdown only when
inline blame is enabled.
- Tested with `show_commit_summary` toggled when location is
`status_bar` (for inline location, nothing is changed)

Areas that could use more testing:
- Remote (collab) editors ? 

Reviewers can test by setting the following in `settings.json` and
moving the cursor across blamed lines:

```json
{
  "git": {
    "inline_blame": {
      "enabled": true,
      "location": "status_bar"
    }
  }
}
```

## Showcase

<details>
  <summary>Click to view showcase</summary>

### Video

https://github.com/user-attachments/assets/6d9f490d-7bf3-473c-9562-8351546dfaf9

### Screenshots
<img width="894" height="749" alt="image"
src="https://github.com/user-attachments/assets/c6a49008-899d-4a0c-9098-1ffb9e28252b"
/>


</details>

Release Notes:

- Added a `git.inline_blame.location` setting to render current-line git
blame in the status bar instead of inline.
2026-06-29 05:50:31 +00:00
Bing Wang 7a00c48ddc git_panel: Fix stale Git status entries for moved directories (#59934)
# Objective

Fix stale Git status entries for moved directories

## Solution

Coalesce changed paths before scanning and remove cached descendant
statuses when a directory disappears from the current status set.



## Self-Review Checklist:

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



---

Release Notes:

- Fixed stale Git status entries for moved directories
2026-06-29 02:54:40 +00:00
Kirill Bulatov fe2c2f4000 Fix code lens not being resolved in remote workflows (#59999)
Follow-up to https://github.com/zed-industries/zed/pull/54100
Closes https://github.com/zed-industries/zed/issues/59122

Original PR overlooked that the resolve was not handled from the remote
hosts at all...
Also, fixes the re-fetch of code lens not taking new language servers
into account: before, it exit early whilst now it actually re-fetches
the lens for the new servers.

Before:

<img width="1728" height="1084" alt="before"
src="https://github.com/user-attachments/assets/9ee8205b-084b-4409-9abc-18c4ddb9c4e9"
/>

After:

<img width="1728" height="1084" alt="after"
src="https://github.com/user-attachments/assets/16ad76dc-25e1-4257-80dc-b5aeabc9a4ef"
/>


Release Notes:

- Fixed code lens not being resolved in remote workflows
2026-06-28 14:44:44 +00:00
Artem KalytiukandClaude Opus 4.8 c43971d69c Handle dynamic registration of semantic tokens capability (#60015)
In C# files nothing gets semantic highlighting — class fields and other
identifiers are colored by tree-sitter only, so a private field looks
the same as a plain local variable.

The reason: Roslyn (the C# language server) doesn't declare
`semanticTokensProvider` statically in its `initialize` response. It
registers it **dynamically** (`client/registerCapability`), and only
when the client advertises
`textDocument.semanticTokens.dynamicRegistration = true`. Zed advertised
`false` and didn't handle such a registration, so Roslyn never offered
semantic tokens at all. (rust-analyzer/gopls are unaffected — they
declare the capability statically.)

This is the first of two PRs. This one makes Roslyn actually **send**
semantic tokens. The companion PR (#60027) maps Roslyn's C#-specific
token types to theme styles — without it the tokens arrive but most are
dropped, since their types aren't in Zed's default rules.

## Solution

- Advertise `textDocument.semanticTokens.dynamicRegistration = true`.
- Handle the `textDocument/semanticTokens` registration and
unregistration so the capability is stored, following the existing arms
for `documentLink`, diagnostics, etc.

## Testing

- Added a test that dynamically registers and unregisters
`textDocument/semanticTokens` and checks the stored capability appears
and is cleared.
- Verified manually against Roslyn on a C# project: Zed now sends
`textDocument/semanticTokens/full` and gets tokens back; before this
change there was no semantic-token traffic at all.

## Self-Review Checklist:

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

---

Release Notes:

- Support dynamic registration of the `textDocument/semanticTokens`
capability.

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 13:48:10 +00:00
Kirill Bulatovandzed-zippy[bot] 9afbcb75c5 Refresh code lens after dynamic registration (#60009)
Follow-up to https://github.com/zed-industries/zed/pull/54100

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

Release Notes:

- Fixed code lens not being refresh after the corresponding capability
was dynamically registered

---------

Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-28 09:17:34 +00:00
Matt Van HornandCole Miller 585e40a6dc git_ui: Preserve in-progress commit message across reconnect (#58180)
Losing the connection on a remote project, or restarting Zed, while
editing a git commit message cleared the in-progress text, because the
Git panel rebuilds the commit buffer from the repository and discards
unsent input.

This persists the draft, scoped to the active repository's work
directory, in the panel's serialized state and restores it when the
panel is rebuilt from that state: at construction when the active
repository already matches, and again in `reopen_commit_buffer` once the
commit buffer loads. The restore only applies to an empty target buffer
whose work directory matches the active repository, so it never replays
committed or cleared text and never leaks a draft across repositories.
The persisted draft is cleared after a successful commit.

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

Release Notes:

- Fixed in-progress git commit messages being cleared when a remote
project reconnects or Zed restarts

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-06-27 20:29:20 +00:00
Lukas Wirth 42edf2fea1 Implement telemetry for the remote server (#59692)
# Objective

Telemetry events generated **on a remote server** were silently dropped,
and all remote telemetry that *was* reported got attributed to the local
client's OS.

## Solution

This PR makes server-originated events flow to the telemetry pipeline
and attributes them to the actual remote host (connection type, OS,
version, architecture), plus adds a transport-agnostic connection event.

## Additional Notes

This removes the "SSH Project Opened" event and replaces it with a
"Remote Connection Established" one that has more structured info and is
also more useful in where it gets invoked.

The server unconditionally sends back telemetry to the client, the
client is then responsible for filtering on whether telemetry is enabled
by the user or not as the server does not have knowledge of those
settings itself.

Release Notes:

- N/A
2026-06-23 05:53:33 +00:00
guopenghuiandYara 🏳️‍⚧️ 9079f2fa95 Add named bookmark support (#57491)
Adds support for named bookmarks while preserving the existing unnamed
bookmark workflow.

Main changes:
- Keeps `ToggleBookmark` as the quick unnamed bookmark action.
- Adds `ToggleNamedBookmark`, which prompts for a bookmark name when
adding a new bookmark and removes an existing bookmark on the same line,
including unnamed ones.
- Adds `EditBookmark` support for renaming existing bookmarks.
- Persists bookmark names in workspace storage.
- Adds a project bookmarks picker that supports filtering by bookmark
name and relative path, with highlighted matches.
- Updates bookmark storage and tests to carry bookmark names through
serialization, restoration, navigation, and project-level listing.

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

Video
toggle:


https://github.com/user-attachments/assets/a725b9cf-ac37-4ebc-85cc-ee820452c043

rename:


https://github.com/user-attachments/assets/a6d0d0c1-511b-4fb7-ae5d-22c55d1a075f


Release Notes:

- Add named bookmark support

---------

Co-authored-by: Yara 🏳️‍⚧️ <git@yara.blue>
2026-06-22 20:47:44 +00:00
6a6fcbebc4 Add preview to pickers and make them resizable (#59604)
Overhauls Zed's pickers to make them resizable and give them a preview.

Closes #8279 

### Background
The most requested Zed feature has the last year has been a [Telescope
like search box](https://github.com/zed-industries/zed/issues/8279)
[discussion](https://github.com/zed-industries/zed/discussions/22581).
To understand why this is so popular we need to understand search can
serve thee goals:
- Navigation: fuzzy search is faster & easier then clicking in a file
tree
- Exploration: example, find a function by a word in its doc comment
- Collecting: example, getting a list of functions to change

The project search which shows results in a multibuffer is the perfect
way to operate on a list of items. Navigation and Exploration need a lot
of context around each result and offer fast navigation between them.
For both of these live searching is also critical.

The `telescope UI` is a picker with a preview to the right or below.
It's offered in various editors and IDE's most famously Neovim (through
the Telescope plugin), IntelliJ (natively), Helix (natively) and of
course VScode (plugins) and it's _many_ forks.

While having a UI like that for text search (our project search) is most
requested the UX pattern is applied widely, from `find_all_references`
to `bookmarks`. It enhances most pickers. Note that we have over 50
different picker modals!

The community has tried to build something like this for Zed:
- https://github.com/zed-industries/zed/pull/44530
- https://github.com/zed-industries/zed/pull/45307
- https://github.com/zed-industries/zed/pull/46478
- https://github.com/zed-industries/zed/pull/43790

These all became huge PR's that we could not merge for various reasons.
This is a really hard feature to integrate in Zed!
This PR got started as https://github.com/zed-industries/zed/pull/46478
and supercedes that.

### Design
- Extend pickers to support an optional preview with minimal changes to
the pickers themselves.
- Make pickers resizable.
- Complement the existing search do not replace it by having both UI's
share the underlying search and allow freely switching between them.
- Allow extending the preview to things other then files.
- Maintain a clean design on all the pickers.

### Heigh level Implementation overview
- Adds an `Option<Preview>` to `Picker`
- Gives `PickerDelegate` a method to communicate a preview to the Picker
- Overhaul the way pickers are drawn to allow for resizing them.
Implemented on the `Shape` and `SizeBouds` structs.
- Adds a high level way to draw the `footer` and `editor` so we do not
need to change much to the pickers.
- Adds a new text finder Picker
- Adds a way to take a running search from project search and hand it to
the text finder Picker and the other way round
- Give the file finder a preview

### Next steps
A more detailed list and how to help out will be added to the tracking
issue for [Pickes with
previews](https://github.com/zed-industries/zed/issues/56037)
- Add more previews to more pickers!
- Enable selectioning multiple items in pickers and performing actions
on those
- Open selected items in a multibuffer
- Add a way to restore the last picker
- Make popovers (picker attached to some menu) resizable as well

## Self-Review Checklist:

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

## Showcase
TODO (will be done post merge)

---

Release Notes:
- Added resizing via dragging to all picker modals. 
- Added a preview to the File finder, the preview can be to the right or
below.
- Added a Text finder picker with a preview as alternative project
search UI. The search is shared and allowes switch between UIs while
running.

---------

Co-authored-by: ozacod <47009516+ozacod@users.noreply.github.com>
Co-authored-by: ozacod <ozacod@users.noreply.github.com>
Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-06-19 17:43:07 +00:00
Lukas Geiger aed5023e80 git: Use fast access check for repository in git panel (#59514)
# Objective

The git panel currently runs a full `git status` for checking whether
`git` has access to the repository. This was introduced in #43693 and
currently runs on every file save which is problematic for large repos
where `git status` runs a lot of computation.

## Solution

This PR switches to a simple `git rev-parse` command which is cheap and
achieves the same goal.

## Testing

I added a unittest.

## Self-Review Checklist:

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

/cc @dinocosta

Release Notes:

- Improve performance of git access checks in git panel
2026-06-18 07:47:47 +00:00
5bdcb12042 Fix project grouping for Git repo subdirectories (#57998)
Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] Unsafe blocks (if any) have justifying comments
  - No unsafe blocks added.
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
- No new UI components; behavior better matches user intent for opened
folders.
- [x] Tests cover the new/changed behavior
  - Added sibling-subdirectory project group regression coverage.
- Extended subfolder Git-status test to ensure Git still uses the parent
repo while project identity stays at the opened folder.
- [x] Performance impact has been considered and is acceptable
- Change adds one small enum/optional field check when computing
worktree paths; no meaningful performance impact expected.

Closes #57997

Release Notes:

- Fixed project grouping for opened subdirectories that share the same
parent Git repository.

## Screenshots

### Before
<img width="334" height="224" alt="Screenshot 2026-05-28 at 5 29 55 PM"
src="https://github.com/user-attachments/assets/ad5b13c5-11a7-4fa4-a074-a519521641da"
/>
<img width="485" height="201" alt="Screenshot 2026-05-28 at 5 28 36 PM"
src="https://github.com/user-attachments/assets/9cd2c138-92f5-4ff2-bf8f-21cdbeff0b79"
/>

### After

<img width="343" height="253" alt="Screenshot 2026-05-28 at 5 29 40 PM"
src="https://github.com/user-attachments/assets/56a4dca7-f0a1-4530-8c89-3c4773b90486"
/>
<img width="420" height="206" alt="Screenshot 2026-05-28 at 5 29 22 PM"
src="https://github.com/user-attachments/assets/d118340a-955e-4483-9888-4b566f59b931"
/>

---------

Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
2026-06-17 01:53:23 +00:00
Richard Feldman fdebc23ccc Prevent archival of manually-created worktrees (#58275)
This fixes archive cleanup for agent threads so Zed only removes
worktrees it explicitly created, rather than treating every linked
worktree under the configured managed directory as safe to delete. When
Zed creates a worktree, it now records it in the local database along
with the creation time of the worktree's git metadata directory
(`.git/worktrees/<name>/`). Archive planning requires that record, and
right before deleting anything, Zed re-stats the directory and compares
creation times: if the worktree was removed and recreated outside Zed
(or the time can't be read at all), deletion is skipped and the stale
record is dropped. Every failure mode fails safe by leaving the
directory untouched.

For remote (SSH) projects, the stat runs on the remote host via a new
`GitWorktreeCreatedAt` request. Worktrees created by a different Zed
install (another release channel, or another machine connecting to the
same host) have no record in the local database and are therefore never
auto-archived, which is the intended conservative behavior.

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

Closes AI-352

Release Notes:

- Fixed archiving an agent thread incorrectly deleting manually-created
git worktrees.
2026-06-16 15:36:59 +00:00
Cameron Mcloughlin 1b61228523 Settings UI agent providers (#58876)
Manage various LLM settings (previously in agent panel) in settings UI.

Behind a feature flag, not staff shipped

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-06-16 15:07:25 +00:00
saberoueslati 7d516a1a91 Anchor sticky scroll to symbol name rows (#56333)
## Context

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

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

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

Closes #55587

Manual video of the test :

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


## How to Review

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

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

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

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

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

## Self-Review Checklist

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

Release Notes:

- Fixed sticky scroll anchoring to unhelpful context rows for multiline
signatures when symbol metadata provides a more precise name range.
2026-06-15 11:03:26 +00:00
Lukas GeigerandLukas Wirth 4fbe456384 git: Optimize git HEAD state resolution (#59044)
Currently zed runs `git rev-parse HEAD` and `git show` sequentially to
get the git `HEAD` state in `compute_snapshot`.

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

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

Self-Review Checklist:

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

Release Notes:

- Improved performance of git HEAD state resolution

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-06-15 10:05:36 +00:00
Lukas Geiger 3f2c5b299c git: Reduce number of spawned git processes when retrieving remote URLs (#59053)
Currently Zed fetches remote URLs by sequentially calling `git remote
get-url origin` and `git remote get-url upstream`.
This PR introduces a new `remote_urls` function which uses `git remote
-v` to retrieve all remote fetch URLs with a single git process.

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

Probably best to review both commits separately.

Self-Review Checklist:

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

Release Notes:

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

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

Self-Review Checklist:

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


Release Notes:

- Reduce git processes run on every file change
2026-06-15 07:12:57 +00:00
Lukas Wirth 423d5b64b5 multi_buffer: Don't eagerly clone BufferSnapshot in range_to_buffer_ranges (#59190)
Both cloning and dropping of these has quite a bit of overhead (despite
them being snapshots), so avoid where possible, especially in display
map syncing

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-06-12 12:27:28 +00:00
Richard Feldman 24d400d04c Persist dev container suggestion dismissal across git worktrees (#58576)
Opening a new git worktree of a repository that has a dev container
configuration re-prompted you to reopen in a dev container, even after
you'd clicked "Don't Show Again" in another worktree of the same repo.
The dismissal was keyed on each worktree's own absolute path, so sibling
worktrees never saw the stored choice.

This keys the dismissal on the repository's common Git directory
instead, which is shared across all linked git worktrees of the same
repo, so dismissing in one worktree now suppresses the prompt in the
others. Projects that aren't Git repositories fall back to the worktree
path as before.

Closes AI-357

Release Notes:

- Fixed the "Reopen in Dev Container" suggestion re-appearing in new git
worktrees after choosing "Don't Show Again"
2026-06-11 20:36:42 +00:00
23237ac456 Improve didChangeWatchedFiles handler performance (#59078)
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: John Tur <john-tur@outlook.com>
Co-authored-by: Ben Kunkle <ben@zed.dev>
2026-06-10 23:52:00 +00:00
Tom Houlé 57a3586854 debugger: Fix running ignored Rust tests in nested modules (#54787)
Debugging an ignored Rust test whose code lives in a nested module (e.g.
`variant_get::test::get_complex_variant`) sometimes exited immediately
with "0 tests matched", When the test name itself came from tree-sitter
runnable capture, which sees only the bare function identifier. So
`--exact get_complex_variant` filtered out the actual test.

The fix is to only append `--exact` when the name contains `::`.
rust-analyzer's `experimental/runnables` produces qualified paths and
keeps the disambiguation introduced in #43110, and the runnables from
tree-sitter no longer break for nested modules.

Closes #51810.

Release Notes:

- Fixed debugging Rust tests in nested modules sometimes immediately
exiting with "0 tests matched".
2026-06-10 13:06:15 +00:00
7a469725d3 Refactor BufferDiff to allow multiple diffs to share the same base text buffer (#58266)
This PR changes how base texts are managed by the `buffer_diff` crate,
to enable keeping two diff entities alive that share the same base text
buffer entity. Previously, each diff owned its own base text buffer and
edited it when calling `BufferDiff::set_snapshot`, so the only way to
reuse the same base text between two diffs was to have two independent
buffers for it, which is pretty inefficient.

After this PR, each diff still has a base text buffer, but
`set_snapshot` doesn't edit it. Instead, that responsibility moves into
the caller. For updating the base text buffer, this PR also introduces a
new pair of APIs, `Buffer::snapshot_with_edits` and
`Buffer::fast_forward`, which allow us to move the parsing of the new
base text into the background and then install the new syntax tree
synchronously on the foreground.

The git store uses the low-level APIs `set_snapshot` and `fast_forward`
directly, and manages the head text and index text buffers itself
(garbage-collecting them when they're no longer needed); this enables
adding an `open_staged_diff` API which returns a diff between the
managed index buffer and the managed head buffer (the latter is also
used for the uncommitted diff's base text). Other downstreams don't need
to reuse a base text buffer, and those have been migrated to use the
high-level `set_base_text` API, which now calls `set_snapshot` and
`fast_forward` internally, with a guard to prevent concurrent updates.

Another change worthy of note is that we now always diff the old base
text with the new base text to create `snapshot_with_edits`.

There are also some incidental bug fixes:
- Fixed an issue where a dangling weak unstaged diff could stick around
in the git store forever
- Restored the `IndexMatchesHead` optimization that had become
inoperative in the remote case
- Fixed a crash in the multibuffer due to the handling of
`BufferDiffEvent::LanguageChanged`, which could cause the multibuffer to
have transforms that were inconsistent with the diff base text.

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-81P

Release Notes:

- Fixed a rare crash that could occur while using the uncommitted diff.

---------

Co-authored-by: Ben Kunkle <ben@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
2026-06-09 20:13:13 +00:00