Commit Graph
84 Commits
Author SHA1 Message Date
JaceandChristopher Biscardi 0d67b1a7ff search: Fix toggle soft wrap not working while the search bar is focused (#61150)
Closes #34698

The buffer search query input is itself an editor, so dispatching
`editor::ToggleSoftWrap` from the command palette while the search bar
had focus toggled soft wrap on the single-line query editor (with no
visible effect) and never reached the searched editor.

This intercepts the action on the search bar in the capture phase and
applies it to the active searchable item, the same way `ToggleFoldAll`
is already relayed. Focus stays in the search bar, so you can keep
typing your query. `Editor::toggle_soft_wrap` and
`Editor::soft_wrap_mode` become `pub` (matching
`fold_all`/`has_any_buffer_folded`, which the existing `ToggleFoldAll`
relay already uses).

Includes a regression test that fails without the fix: it deploys the
search bar, dispatches `ToggleSoftWrap` with the query editor focused,
and asserts the searched editor's wrap mode changes while focus remains
in the search bar.

Release Notes:

- Fixed `editor: toggle soft wrap` doing nothing when invoked while the
buffer search bar was focused

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-07-21 06:14:52 +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
Danilo Leal e41a55c3c0 Improve diff tabs toolbar design (#60464)
This PR adds a bunch of design improvements to the toolbar of (tab)
views that display diffs: the uncommitted changes, branch diff, and
agent diff tabs. This involves adjusting spacing, sizing, and other
small tweaks across all of these views, including touching up the
divider component API a little bit, adjusting Git icons design, adding
diff stat numbers to the uncommitted changes tab so its consistent with
the others, and more (e.g., moving the split buttons into its own
component to ensure they look the same across all uses). Ended up also
going on a slight de-tour to make all uses of the split button in the
Git panel consistent design-wise.

All in all, this is just tidying up the design of all of these surfaces
that are all relatively similar.

| Branch Diff | Uncommitted Diff | Single-file Diff | Git Panel |
|--------|--------|--------|--------|
| <img width="800" alt="Screenshot 2026-07-06 at 11  25@2x"
src="https://github.com/user-attachments/assets/4ebf87e7-c52d-41d9-9de3-7944125114a1"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11  25 2@2x"
src="https://github.com/user-attachments/assets/51ccd2eb-904b-455a-a708-b4cb50b3a7cb"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11  26@2x"
src="https://github.com/user-attachments/assets/6ae7df68-d1bd-4d36-a250-ba16e43c4e8e"
/> | <img width="800" alt="Screenshot 2026-07-06 at 11  26 2@2x"
src="https://github.com/user-attachments/assets/e032bc60-4551-41f0-b578-90ed305167c2"
/> |

Release Notes:

- Added diff stat numbers to the uncommitted changes view.
2026-07-06 15:46:44 +00:00
Sathwik ChirivelliandChristopher Biscardi 97e5d4f630 solo_diff_view: Show changes only by default (#59958)
# Objective

- Default the solo diff view to show changed hunks with excerpted
context instead of expanding the entire file.
- Closes https://github.com/zed-industries/zed/issues/59489

## Solution

- Initialize the solo diff editor with excerpts around changed hunks.
- Add a header toggle for switching between the excerpted changes-only
view and the full-file view.
- Keep both sides of the split diff visually aligned when excerpts are
collapsed.

## Testing

- `cargo check -p git_ui`
- `cargo test -p git_ui`

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

## Showcase

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

Changes-only default view:
<img width="1624" height="1030"
alt="solo_diff_view_new_default_changes_only_view"
src="https://github.com/user-attachments/assets/c6fb937e-8882-415c-8476-b9c3019c152e"
/>


Toggled full-file view:
<img width="1624" height="1030"
alt="solo_diff_view_toggled_to_full_file_view"
src="https://github.com/user-attachments/assets/3d736d00-178a-4dfa-b1ff-d3d15e33b30e"
/>

</details>

---

Release Notes:

- Improved solo diff view to show changed hunks by default with a toggle
for viewing the full file.

---------

Co-authored-by: Christopher Biscardi <chris@christopherbiscardi.com>
2026-06-29 02:59:25 +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
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
Anthony Eid 34c47afbc1 Fix split diff stale scroll anchor crash (#58688)
This crash occurred when the left hand side (LHS) editor in the split
diff retained a stale shared scroll handler after the split editor
unsplits. I added an invariant check to our randomized companion display
map tests to prevent regressions here and explicitly make LHS editor set
a native scroll anchor when unsplitting.

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:

- Fix crash that could occur when unsplitting a side by side diff view
2026-06-05 18:25:37 +00:00
Sathwik ChirivelliandDanilo Leal 298222a756 git_ui: Add split controls to commit view (#58163)
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

Summary:

- Added split/unified diff controls to the commit history commit view
using `SplittableEditor`.
- Kept commit messages separate from file diffs with an 8-line
scrollable message panel.
- Fixed split setup edge cases and async/test type mismatches from the
commit view changes.

Verification:

- `cargo check -p git_ui`
- `cargo check -p git_ui --tests`
- `cargo check -p editor --tests`
- `./script/clippy -p git_ui`
- `git diff --check`

Release Notes:

- Improved the commit history diff view by adding the ability to toggle
the split diff mode.

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-06-01 22:46:12 +00:00
Kirill Bulatov 4bc769a328 Make project panel to auto reveal multi buffer excerpts with latest selection (#57236)
Make non-singleton editors to return project paths by adding a `fn
active_project_path`: this had been added as `fn project_path` and
similar already, so the PR replaced those methods with the generic one
now.

Before:


https://github.com/user-attachments/assets/d0773e18-3910-4c5b-bcb3-a742f9bf9691


After:


https://github.com/user-attachments/assets/e7a3f13e-9649-4564-a7e6-dccf54f8c000


Release Notes:

- Made project panel to auto reveal multi buffer excerpts with latest
selection
2026-05-25 11:53:12 +00:00
Kirill Bulatov 486848af1e Remove code lens from the diff view (#56726)
RHS does not show code runnables already, and lens blocks break the
background highlights, hence remove them too.

Before:

<img width="1728" height="1084" alt="before"
src="https://github.com/user-attachments/assets/6e942568-dcbf-4624-86f6-7f3f31d01d31"
/>

After:

<img width="1728" height="1084" alt="Screenshot 2026-05-14 at 11 13 05"
src="https://github.com/user-attachments/assets/ec3bfcb9-daab-4a33-b799-db86ac352488"
/>

Release Notes:

- Removed code lens from the diff view
2026-05-14 09:39:44 +00:00
Nathan Sobo 1af4a3a2e1 Fix macOS find query seeding (#56681)
Closes #55619

### Summary

- Route `buffer_search::UseSelectionForFind` through
`BufferSearchBar::deploy` instead of updating the query editor directly.
- Add an explicit seed-query override to `deploy`, so the Cmd-E action
can force `SeedQuerySetting::Always` while regular deploy callers
continue to pass `None` and respect the user’s
`seed_search_query_from_cursor` setting.
- By going through `deploy`, Cmd-E now also runs the search path that
keeps buffer-search navigation state in sync:
  - shows/initializes the search bar for the active searchable item
  - applies the seeded query via `search_suggested`
- calls `search`, which updates the query editor, search options, active
search query, search history, and macOS find pasteboard
  - refreshes `searchable_items_with_matches` and `active_match_index`
  - activates the current match after the search completes
- This ensures the subsequent Cmd-G action has the expected active
query, match list, search token, and active match index to select the
next result.
- Add a macOS-only end-to-end regression test using the default macOS
keymap with `simulate_keystrokes("cmd-e")` and
`simulate_keystrokes("cmd-g")`.

### Validation

- `cargo test -p search test_cmd_e_then_cmd_g_uses_selection_for_find`
- `cargo fmt --check --package search --package zed_actions`
- `./script/check-keymaps`
- `cargo check -p search`
- `cargo check -p workspace`
- `cargo check -p vim`

Release Notes:

- Fixed macOS Cmd-E/Cmd-G find behavior so Cmd-E seeds find from the
cursor or selection and Cmd-G advances through the newly seeded matches.
2026-05-13 23:35:10 +00:00
Sathwik Chirivelli cb67f90134 Fix multibuffer initialization based on RHS state (#56058)
This update modifies the initialization of the left-hand side
multibuffer in the SplittableEditor. It now checks if the right-hand
side multibuffer is a singleton and uses a
`MultiBuffer::without_headers` instead.


Before Screenshot:
<img width="1624" height="1030" alt="Screenshot 2026-05-07 at 7 30
16 PM"
src="https://github.com/user-attachments/assets/3d963703-309c-42e4-b2be-fe64bd9c0a06"
/>

After Screenshot:
<img width="1624" height="1030" alt="Screenshot 2026-05-07 at 7 32
48 PM"
src="https://github.com/user-attachments/assets/51668319-6a34-47df-b8b1-8bf58b86407e"
/>


Self-Review Checklist:

- [x] I've reviewed my own diff for quality, security, and reliability
- [x] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)



Release Notes:
- Optimized multibuffer creation by conditionally using headers based on
RHS state.
2026-05-07 15:21:08 +00:00
Cole Miller d5426f5837 Fix mismatched excerpts in split agent diff (#55629)
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

Release Notes:

- Fixed excerpts not matching in the agent diff when in the split view.
2026-05-04 11:56:06 +00:00
Tim Vermeulen 023c6d497d editor: Fix split diff spacer calculation for non-row-aligned patch groups (#53098)
Fixes a bug in the split diff spacer calculation when a patch group
starts mid-row, sometimes causing extra spacers to be inserted.

`spacer_blocks` already explicitly handles the case where `first_point`
isn't at the start of `edit_for_first_point.old`, but the `while let
Some(source_point) = source_points.next()` loop that follows implicitly
assumes that `source_point` is at the start of `current_range`, which in
turn seems to be based on the assumption that `current_range` starts at
the beginning of a row. As it turns out, `current_range` isn't
guaranteed to start at the beginning of a row, which can sometimes lead
to incorrect spacer blocks being inserted.

This addresses that by moving the existing `if
edit_for_first_point.old.start < first_point` logic into the loop body
as `if current_edit.old.start < current_boundary` in order to handle any
non-row-aligned patch groups, not just the first one.

Here's an example of how this bug could manifest:


https://github.com/user-attachments/assets/1d3a5b4c-e4ad-4d87-804b-c4390d25f408

After:


https://github.com/user-attachments/assets/b15acc62-33fe-4154-82e5-5cdf1806ffa7

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 incorrect spacer blocks sometimes appearing in the split diff
view when editing the file.
2026-04-27 10:10:48 +00:00
Finn EversandDanilo Leal c49ffd1e88 Fix bad GitHub merge queue merge (#54721)
No, sadly, the title is not a typo. See
https://www.githubstatus.com/incidents/zsg1lk7w13cf for the context.
I'll read with joy and popcorn through that root cause analysis.

It makes literally zero sense what happened here, but for some completly
bonkers reason GitHub completely messed up the merge queue with
https://github.com/zed-industries/zed/pull/54632.

I have no idea how it happened. It makes literally zero sense. A PR
going into the merge queue should have the same LoC when getting out of
it. GitHub obviously does not check this. GitHub causes extra work with
a feature that is supposed to save time.

Thanks, I guess.

Release Notes:

- N/A

---------

Co-authored-by: Danilo Leal <daniloleal09@gmail.com>
2026-04-23 23:47:30 +00:00
Danilo Leal 184e1d93e3 branch_picker: Add button to filter remote branches (#54632)
This PR brings back the button to filter remote branches when accessing
the title bar's branch picker with the mouse. It was unintentionally
removed when we introduced the new worktree picker.

Release Notes:

- N/A
2026-04-23 18:26:44 +00:00
Lukas Wirth d93337bc4d agent_ui: Enable split diff view in agent diff (#54638)
Release Notes:

- Enable split diff view in agent diff
2026-04-23 15:23:54 +00:00
NaritaHARUKIandLukas Wirth d87d817aa4 Add side-by-side split diff view to FileDiffView (#50046)
## Summary
- Enable VSCode-like side-by-side file comparison in FileDiffView using
SplittableEditor
- Leverages existing SplittableEditor infrastructure that ProjectDiff
already uses
- Controlled by the user's `diff_view_style` setting (split/unified)

## Changes
- `crates/git_ui/src/file_diff_view.rs`: Refactored to use
SplittableEditor instead of plain Editor (+66/-30 lines)

## Test plan
- [ ] Open a file with git changes and verify the diff view renders
correctly
- [ ] Toggle between split and unified diff view styles via settings
- [ ] Verify side-by-side comparison shows old/new content correctly

Release Notes:

- Enabled side by side diffs in the file diff view

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
2026-04-23 10:08:01 +00:00
72890cff6a git: Improve diff performance (#54435)
Previously, passing an empty range to `range_to_buffer_range` would
return no ranges, which would trigger a fallback case in the git diff
that caused the entire multibuffer to be invalidated every frame.

This PR fixes `range_to_buffer_range`, so that it returns a sensible
range if the input range is empty, preventing the fallback behaviour and
edit expansion.

Self-Review Checklist:

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

Closes #ISSUE

Release Notes:

- N/A or Added/Fixed/Improved ...

---------

Co-authored-by: Cole Miller <cole@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
2026-04-22 02:42:11 +00:00
Conrad Irwin 4f6eeb0718 Fix cmd-e on macOS to behave more like it should (#54451)
Closes #50578

Release Notes:

- Fixed cmd-e on macOS to work when `seed_search_query_from_cursor` has
been changed
2026-04-21 19:54:02 +00:00
Cole Miller 22ee751848 git: Fix a panic when updating the split diff (#54352)
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

Release Notes:

- Fixed a panic when using the split diff view.
2026-04-20 18:33:42 -04:00
Lukas Wirth d3b388152b editor: Enable diagnostics underlines in split editors (#54295)
Release Notes:

- Enabled diagnostic underlining in the split editor views
2026-04-20 17:12:32 +02:00
30b1051cd8 Require multibuffer excerpts to be ordered and nonoverlapping (#52364)
TODO:
- [x] merge main
- [x] nonshrinking `set_excerpts_for_path`
- [x] Test-drive potential problem areas in the app
- [x] prepare cloud side
- [x] test collaboration
- [ ] docstrings
- [ ] ???

## Context

### Background

Currently, a multibuffer consists of an arbitrary list of
anchor-delimited excerpts from individual buffers. Excerpt ranges for a
fixed buffer are permitted to overlap, and can appear in any order in
the multibuffer, possibly separated by excerpts from other buffers.
However, in practice all code that constructs multibuffers does so using
the APIs defined in the `path_key` submodule of the `multi_buffer` crate
(`set_excerpts_for_path` etc.) If you only use these APIs, the resulting
multibuffer will maintain the following invariants:

- All excerpts for the same buffer appear contiguously in the
multibuffer
- Excerpts for the same buffer cannot overlap
- Excerpts for the same buffer appear in order
- The placement of the excerpts for a specific buffer in the multibuffer
are determined by the `PathKey` passed to `set_excerpts_for_path`. There
is exactly one `PathKey` per buffer in the multibuffer

### Purpose of this PR

This PR changes the multibuffer so that the invariants maintained by the
`path_key` APIs *always* hold. It's no longer possible to construct a
multibuffer with overlapping excerpts, etc. The APIs that permitted
this, like `insert_excerpts_with_ids_after`, have been removed in favor
of the `path_key` suite.

The main upshot of this is that given a `text::Anchor` and a
multibuffer, it's possible to efficiently figure out the unique excerpt
that includes that anchor, if any:

```
impl MultiBufferSnapshot {
    fn buffer_anchor_to_anchor(&self, anchor: text::Anchor) -> Option<multi_buffer::Anchor>;
}
```

And in the other direction, given a `multi_buffer::Anchor`, we can look
at its `text::Anchor` to locate the excerpt that contains it. That means
we don't need an `ExcerptId` to create or resolve
`multi_buffer::Anchor`, and in fact we can delete `ExcerptId` entirely,
so that excerpts no longer have any identity outside their
`Range<text::Anchor>`.

There are a large number of changes to `editor` and other downstream
crates as a result of removing `ExcerptId` and multibuffer APIs that
assumed it.

### Other changes

There are some other improvements that are not immediate consequences of
that big change, but helped make it smoother. Notably:

- The `buffer_id` field of `text::Anchor` is no longer optional.
`text::Anchor::{MIN, MAX}` have been removed in favor of
`min_for_buffer`, etc.
- `multi_buffer::Anchor` is now a three-variant enum (inlined slightly):

```
enum Anchor {
    Min,
    Excerpt {
        text_anchor: text::Anchor,
        path_key_index: PathKeyIndex,
        diff_base_anchor: Option<text::Anchor>,
    },
    Max,
}
```

That means it's no longer possible to unconditionally access the
`text_anchor` field, which is good because most of the places that were
doing that were buggy for min/max! Instead, we have a new API that
correctly resolves min/max to the start of the first excerpt or the end
of the last excerpt:


```
impl MultiBufferSnapshot {
    fn anchor_to_buffer_anchor(&self, anchor: multi_buffer::Anchor) -> Option<text::Anchor>;
}
```
- `MultiBufferExcerpt` has been removed in favor of a new
`map_excerpt_ranges` API directly on `MultiBufferSnapshot`.

## Self-Review Checklist

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

Release Notes:

- N/A

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Conrad <conrad@zed.dev>
2026-04-01 17:25:32 +00:00
Max Brunsfeld 64ee6f919d Automatically switch to unified diffs when diff view is narrower than a configurable "minimum split diff width" (#52781)
Release Notes:

- The git diff diff view now automatically switches from split mode to
unified mode when the pane is narrower than a configurable minimum
column count. You can configure this via the new
`minimum_split_diff_width` setting.
2026-03-30 18:47:50 -07:00
Piotr Osiewicz 5bfedcb023 theme: Split out theme_settings crate (#52569)
Self-Review Checklist:

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

Closes #ISSUE

Release Notes:

- N/A
2026-03-27 14:41:25 +01:00
Lukas Wirth ea1f19183f editor: Replace BreadcrumbText with HighlightedText (#51083)
Remove the BreadcrumbText struct from workspace and use the existing
HighlightedText struct from the language crate instead. The per-segment
font field is replaced by returning an optional Font alongside the
segments from the breadcrumbs() method, since the font was always
uniform across all segments of a given item.

Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-03-13 08:00:22 +00:00
Kirill BulatovandJakub Konka 394cffcefa Do not load runnables and diagnostics in git panel (#51270)
Release Notes:

- N/A

---------

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
2026-03-11 10:51:54 +00:00
DinoandTom Houlé 358bd69df4 Fix expand/collapse all button for splittable editor (#50859)
The "Expand All Files"/"Collapse All Files" button in `BufferSearchBar`
was broken for `SplittableEditor`, which is used in the project diff
view. It was happening because `ProjectDiff::as_searchable` returns an
handle to the `SplittableEditor`, which the search bar implementation
then tries to downcast to an `Editor`, which the `SplittableEditor` did
not support, so both the expand/collapse all buttons, as well as the
collapse state were broken.

Unfortunately this was accidentally introduced in
https://github.com/zed-industries/zed/pull/48773 , so this Pull Request
updates the `Item` implementation for `SplittableEditor` in order for it
to be able to act as an `Editor`.

Release Notes:

- Fix the "Expand All Files"/"Collapse All Files" button in the project
diff view

---------

Co-authored-by: Tom Houlé <tom@tomhoule.com>
2026-03-09 17:45:36 +00:00
Kirill BulatovandConrad Irwin ccbaa099f6 Do not derive symbol highlights if they do not fit into multi buffer (#50948)
Release Notes:

- N/A

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2026-03-09 15:50:44 +00:00
Cole Miller 15d54b3551 git: Fix a panic when searching the split diff (#50211)
This could happen when you initiated a search on the left side, then
toggled into the unified view, then tried to select the next match.

Closes ZED-55G

Release Notes:

- Fixed a panic when toggling the split diff view while searching.
2026-02-26 14:22:08 +00:00
Cole Miller 99b13081de git: Simplify excerpt syncing code for SplittableEditor (#49943)
Closes #ISSUE

Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A
2026-02-25 00:58:56 +00:00
Cole Miller 00b9127309 git: More rigorously test excerpt syncing for split diff, and fix a couple of bugs (#49907)
This PR adds a more rigorous test for the excerpt syncing logic in
`SplittableEditor`, in preparation for refactoring that code, since
we've had some bugs there.

The new test covers
- edits within the RHS multibuffer
- edits to the individual main buffers, not necessarily within the
excerpt bounds of the split diff
- excerpt expansion
- excerpt removal
- excerpt recalculation based on diff hunk ranges

Bugs fixed:
- incorrect edit merging logic in `patches_for_range`
- `merge_excerpts` leaving stale excerpt IDs in `excerpts_by_path`

Before you mark this PR as ready for review, make sure that you have:
- [x] Added a solid test coverage and/or screenshots from doing manual
testing
- [x] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A
2026-02-24 03:33:33 +00:00
Cole Miller 159ebdc4ba git: Fix diff view buttons not working when project diff or branch diff is empty (#49884)
Release Notes:

- git: Fixed a bug where the buttons to toggle the split diff view would
have no effect when the diff being viewed was empty.
2026-02-23 19:28:13 -05:00
Cole MillerandAntonio Scandurra b4415408be git: Fix panic when unstaged diff is recalculated before its primary diff (#49753)
For inverted diff APIs like `hunks_intersecting_base_text_range`, we
need a snapshot of the main buffer to use as context to compare hunk
anchors, convert anchors to points, etc. Previously, we were always
using a snapshot of the main buffer at the time when the diff was
calculated. This worked well for the hunks of the primary `BufferDiff`,
but it's not valid when the diff also has a secondary set of hunks,
because those hunks are recalculated on their own schedule--so it's
possible for the hunks of the secondary diff to contain anchors that are
newer than the original buffer snapshot that was taken at the time the
primary diff hunks were last calculated. This caused a panic when using
these anchors with the original buffer snapshot.

This PR fixes the issue by using the same approach for inverted diffs as
for non-inverted diffs at the multibuffer level: we take a snapshot of
the main buffer at the time when we snapshot the diff state (including
the diff itself), guaranteeing that that snapshot will be new enough to
resolve all the anchors included in both the primary diff and the
secondary diff.

Closes ZED-54J

Release Notes:

- Fixed a panic that could occur when using the branch diff in split
view mode.

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
2026-02-20 17:11:30 -05:00
b0f16818b5 git: Prevent panic when updating excerpts in split diff (#49725)
When using the split view, if the project diff inserts excerpts for the
same buffer using two different `PathKey`s, we panic inside
`LhsEditor::update_path_excerpts_from_rhs` because of an implicit
assumption that `excerpts_for_path()` and `excerpts_for_buffer()` return
the same number of values. This PR addresses that by ignoring any
excerpts for the given buffer that have a different path key from the
provided one.

Release Notes:

- Fixed a crash when using the split diff view.

Co-authored-by: Jakub Konka <kubkon@jakubkonka.com>
Co-authored-by: Eric <eric@zed.dev>
2026-02-20 11:16:14 -05:00
Antonio Scandurra cbec3c90b3 Fix stale folded buffers in split diff view (#49699)
When a buffer is folded in the split diff view and then removed from the
multibuffer (via `remove_excerpts_for_path`), the block map's
`folded_buffers` set retains a stale entry for that buffer ID. Later,
when the split view syncs folded state from the RHS display map to the
LHS, it tries to look up the companion mapping for this stale buffer and
fails because the companion no longer tracks a buffer that's been
removed from the multibuffer.

This originally caused a panic via `.expect()`. This PR:

1. Converts the panic into graceful handling by skipping unmapped
buffers.
2. Actively removes stale entries from `folded_buffers` so they don't
persist as ghost state — ensuring that if the same buffer is later
re-added, it won't incorrectly appear as folded.
3. Adds a regression test covering the full lifecycle: fold → remove →
split → re-add → assert both LHS and RHS report the buffer as not
folded.

Release Notes:

- Fixed a crash in split diff view when a folded buffer was removed and
re-added.
2026-02-20 09:49:31 +00:00
Cole Miller 006ce97969 git: Replace some unwraps with expect (#49683)
Release Notes:

- N/A
2026-02-20 05:18:10 +00:00
Kirill Bulatov 761671b2ae Revert "Enable type on search by default for the project search (#49374)" (#49619)
This reverts commit e477b545b7.

Needs 2 more fixes:

* enter does not move to the first excerpt anymore
* there could be situations when a narrowed search does not decrease the
excerpt enough to see the result onscreen

Release Notes:

- N/A
2026-02-19 16:24:54 +00:00
Jakub Konka 0e06137349 buffer_diff: Reduce number of entity clones in base_text_buffer (#49573)
Release Notes:

- Improved split performance by reducing number of entity clones for
very large pre-loaded multibuffers.
2026-02-19 11:57:43 +01:00
Cole Miller b13f3789ff git: Mitigate panic in split diff (#49546)
Release Notes:

- N/A
2026-02-18 20:16:04 -05:00
Kirill BulatovandCole Miller e477b545b7 Enable type on search by default for the project search (#49374)
Deals with https://github.com/zed-industries/zed/issues/9318
Re-lands https://github.com/zed-industries/zed/pull/42889 with more
fixes to reduce overall flickering

Release Notes:

- Enabled type on search by default for the project search

---------

Co-authored-by: Cole Miller <cole@zed.dev>
2026-02-18 21:39:45 +00:00
Jakub KonkaandLukas Wirth 846b4191c9 editor: More perf work (#49465)
Seems that `SmallVec::clone` is pretty expensive in a generic case, and
specialising it improves the performance quite a bit!

Release Notes:

- Improved performance of different building blocks within the
MultiBuffer.

---------

Co-authored-by: Lukas Wirth <lukas@zed.dev>
2026-02-18 14:20:30 +01:00
Lukas Wirth 2fb5628281 Reduce amount of monomorphizations from FnMut closures (#49453)
Replaces a bunch of `impl FnMut` parameters with `&mut dyn FnMut` for
functions where this is the sole generic parameter.
Release Notes:

- N/A *or* Added/Fixed/Improved ...
2026-02-18 12:00:02 +01:00
Lukas Wirth 75a0e170a1 editor: Improve apply_fetched_hints for many excerpt multibuffers (#49444)
Reuses the new multi buffer api from
https://github.com/zed-industries/zed/pull/49349 for inlay hints

Release Notes:

- Reduced occasional stuttering coming from inlay hints in large
multibuffers
2026-02-18 10:19:08 +01:00
Cole MillerandZed Zippy 00f2db1b39 git: Fix panic in split diff when edits cause excerpts to merge (#49122)
Our strategy for keeping excerpts in sync between the two sides of the
split diff is generally

- mutate the excerpts on the RHS
- pull out the new excerpts for the affected path from the RHS
- translate those ranges to the LHS
- update the LHS excerpts with those ranges

But this can break down when the translated ranges overlap on the LHS
despite the original ranges not overlapping on the RHS. This can happen,
for example, when a large deletion in a file crosses several excerpt
boundaries. It's rare because normally excerpt boundaries in the project
diff and branch diff are adjusted to keep entire diff hunks in view, but
we defer this for dirty files, so it's not hard to trigger it when using
the agent or editing an individual file while the diff is open in
another tab.

Release Notes:

- Fixed a panic that could occur when editing files while the project
diff or branch diff was open.

---------

Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-02-17 01:40:19 +00:00
56290e8341 git: Remove unnecessary block map recomputation when splitting SplittableEditor (#49075)
We had a call to `BlockMap::unfold_intersecting` that ended up
recomputing the entire block map for the RHS _without_ spacers, only to
throw it away in favor of the version with spacers a few lines down. Now
we only sync each block map once in `set_companion`.

Release Notes:

- Improved performance when toggling from the unified diff to the split
diff.

Co-authored-by: Jakub <jakub@zed.dev>
Co-authored-by: Cameron McLoughlin <cameron.studdstreet@gmail.com>
2026-02-13 15:52:04 +00:00
Cole Miller b606c54079 git: Fix misalignment in the split diff when inlays fall at the end of an excerpt (#49078)
- [x] Tests or screenshots needed?
- [ ] Code Reviewed
- [x] Manual QA

Release Notes:

- Fixed misalignment of lines in the split diff when using inlay hints.
2026-02-13 10:31:06 -05:00
a67197b3e2 Re-add MultiWorkspace (#48800)
Release Notes:

- Added agent panel restoration. Now restarting your editor won't cause
your thread to be forgotten.

---------

Co-authored-by: Anthony Eid <56899983+Anthony-Eid@users.noreply.github.com>
Co-authored-by: Eric Holk <eric@zed.dev>
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>
Co-authored-by: Anthony Eid <anthony@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
Co-authored-by: Cameron Mcloughlin <cameron.studdstreet@gmail.com>
2026-02-12 01:06:23 +00:00
Cole Miller 45dc98fb0a git: Disable some more expensive things for the split diff's left-hand side (#48953)
- Conflict UI
- LSP data
- Runnables

Release Notes:

- Improved performance when opening the split diff view.
2026-02-11 21:58:55 +00:00
Cole Miller 2361d858dd git: Enable the split diff for everyone (#48912)
Release Notes:

- Added support for viewing diffs in split ("side by side") mode
2026-02-11 06:28:55 +00:00