BufferEvent::Edited had no way to distinguish local edits from remote
(collaboration) edits. This caused edit prediction behavior to fire on
the guest's editor when the host made document changes.
Release Notes:
- Fixed edit predictions triggering on collaboration guests when the
host edits the document.
---------
Co-authored-by: Ben Kunkle <ben@zed.dev>
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>
Add a `git::RestoreAndNext` action that restores the diff hunk at the
cursor and advances to the next hunk. In the git diff view, the default
restore keybinding (`cmd-alt-z` on macOS, `ctrl-k ctrl-r` on
Linux/Windows) is remapped to this action so users can quickly restore
hunks in sequence. Also refactor `go_to_hunk_before_or_after_position`
to accept a `wrap_around` parameter, eliminating duplicated
hunk-navigation logic in `do_stage_or_unstage_and_next` and
`restore_and_next`.
Release Notes:
- Added a `git: restore and next` action that restores the diff hunk at
the cursor and moves to the next one. In the git diff view, the
default restore keybinding (`cmd-alt-z` on macOS, `ctrl-k ctrl-r` on
Linux/Windows) now triggers this action instead of `git: restore`.
---------
Co-authored-by: Afonso <4775087+afonsograca@users.noreply.github.com>
In `BlockMap::sync`, blocks within an edited region are sorted and
processed sequentially. Each block placement computes
`rows_before_block` by subtracting `new_transforms.summary().input_rows`
from the block's target position. The `Near`/`Below` cases have a guard
that skips the block if the target is already behind the current
progress, but `Above` and `Replace` were missing this guard.
When a `Replace` block (tie_break 0) is processed before an `Above`
block (tie_break 1) at the same or overlapping position, the `Replace`
block consumes multiple input rows, advancing `input_rows` past the
`Above` block's position. The subsequent `position - input_rows`
subtraction underflows on `u32`, producing a huge `RowDelta` that wraps
`wrap_row_end` past `wrap_row_start`, creating an inverted range that
propagates through the display map layers and panics as `begin <= end
(47 <= 0)` in a rope chunk slice.
Add underflow guards to `Above` and `Replace`, matching the existing
pattern in `Near`/`Below`.
Release Notes:
- Fixed a source of underflowing subtractions causing spurious panics
Fixes ZED-5M9
No test as I couldn't quite reproduce this, as the cause is mostly a
guess
Release Notes:
- Fixed a panic in `lsp_symbols_at_cursor` when dealing with diff hunks
Fixes#42444
- Changed `accepts_text_input` on the editor to be more precise.
Previously, it returned `true` only in insert mode. Now it also returns
`true` when an operator is pending.
- On Windows, we disable the IME whenever there is no input handler
which `accepts_text_input`.
- How this improves Vim mode: in insert mode, the IME is enabled; in
normal mode, it is disabled (command keys are not intercepted); when an
operator is pending, the IME is re-enabled.
Release Notes:
- On Windows, the IME is disabled in Vim normal and visual modes.
Closes#50631
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:
- Fixed `formatter: "auto"` silently doing nothing when the first
language server for a language doesn't support formatting (e.g., Dependi
before Tombi for
TOML).
When I am in the middle of editing, pressing Ctrl would
counter-intuitively highlight links even when the mouse cursor is
hidden. This change considers the state of the mouse cursor before
painting links on hover.
Before: Modifier pressed, cursor hidden, link visible
<img width="506" height="518" alt="image"
src="https://github.com/user-attachments/assets/82a59e83-e3cb-490f-b292-148686ec569d"
/>
After: Modifier pressed, cursor hidden (red dot indicates current cursor
position)
<img width="408" height="298" alt="image"
src="https://github.com/user-attachments/assets/c19ed83c-4778-4890-97b9-5155cdcf658b"
/>
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
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed spurious link highlighting when mouse cursor is hidden
Fixes#50776
Turns out `Editor::newline_below` was not respecting the `read_only`
flag because it uses buffer.edit. `Editor::newline` and
`Editor::newline_above` behaved correctly because they used
`editor.edit` which ignores edits if `read_only` is true.
Added an early return if the editor is read only, also added it to
newline/newline_above for clarity.
Release Notes:
- Fixed an issue where newlines could be inserted into read-only editors
Closes#47550
Changes the `auto_indent` setting from a boolean to an enum with three
modes:
- **`full`** (default): Adjusts indentation based on syntax context when
typing (previous `true` behavior)
- **`preserve_indent`**: Preserves the current line's indentation on new
lines, but doesn't adjust based on syntax
- **`none`**: No automatic indentation - new lines start at column 0
(previous `false` behavior)
This gives users more control over indentation behavior. Previously,
setting `auto_indent: false` would still preserve indentation on new
lines, which was unexpected.
Includes:
- Settings migration from boolean to enum values
- Settings UI dropdown renderer
Release Notes:
- Changed `auto_indent` setting from boolean to enum with `full`,
`preserve_indent`, and `none` options
<img width="1373" height="802" alt="Screenshot 2026-01-27 at 16 32 10"
src="https://github.com/user-attachments/assets/b629e1d8-7359-4853-8222-abfa71d6ebe2"
/>
---------
Co-authored-by: MrSubidubi <finn@zed.dev>
Refactor the changes introduced in
https://github.com/zed-industries/zed/pull/50525, in order to remove the
`DisplayMap.clear_folded_buffer` method and update the editor's handling
of `multi_buffer::Event::ExcerptsRemoved` to actually call
`DisplayMap.unfold_buffers`, which correctly updates the `BlockMap`
using its `BlockMapWriter`, ensuring that the block map is synced.
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
- [X] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- N/A
I noticed that the minimap seems to render underlines with the same
thickness as the main editor, which looks a bit off. This becomes much
more noticeable when enabling `semantic_token_rules` (due to the
increased number of underlines):
```json
"global_lsp_settings": {
"semantic_token_rules": [
{
"token_modifiers": ["mutable"],
"underline": true,
},
],
}
```
Looking at the existing code, I found that diagnostic underlines already
check `editor_style.show_underlines` to ensure they are only displayed
in the main editor. To maintain consistency, I applied the same
filtering logic to `chunk_highlight` so that these underlines are no
longer rendered in the minimap.
Before:
<img alt="CleanShot 2026-02-06 at 02 28 31@2x"
src="https://github.com/user-attachments/assets/16401154-23f5-43ef-a7a8-b1035c19e076"
/>
After:
<img alt="CleanShot 2026-02-06 at 02 31 36@2x"
src="https://github.com/user-attachments/assets/979a04be-e585-44be-9c42-4dfab7b89186"
/>
Release Notes:
- N/A *or* Added/Fixed/Improved ...
A vector was being instantiated when the callsite only required an
iterable.
Another part of the code was performing multiple `contains()` lookups on
a vector, and now it does it on a hashed set. This change has required
some extra modifications across the codebase, but the affected sites are
minimal and have been adjusted without major issues.
The changes include some `Hash` derived implementations, which were
proposed in the original `lsp-types` in [[1]], and maybe could be merged
into Zed's fork. I went ahead and used a newtype with a custom `Hash`
implementation that simply called on the structure's public members'
implementations of `Hash`.
The next change includes the removal of a check of the request
capabilities after having already checked the same thing in the call to
`to_lsp_params_or_response()` right before. The result of the `match`
expression should already have returned a `Task::ready()` if the above
mentioned function failed in performing the check that was later
repeated and now removed.
Finally, in the `edits_from_lsp()` method, stable sorting was being
performed when only unstable sorting would suffice. The method can only
sort with respect to the key data, and not the satellite data, as the
latter are the literal strings of the edit. It matters not which one of
a sequence of overlapping edits (with same ranges that thus resolve the
edits for equivalence) should come before the other.
[1]:
https://github.com/gluon-lang/lsp-types/pull/295/changes#diff-b1a35a68f14e696205874893c07fd24fdb88882b47c23cc0e0c80a30c7d53759R540
- [ ] Tests or screenshots needed?
- [ ] Code Reviewed
- [ ] Manual QA
Release Notes:
- Removed a vector allocation where the callsite only required an
iterable.
- Improved multiple lookup operations when deserializing LSP edit
operations.
- Removed a double-check of capabilities after requesting and thus
determining LSP capabilities.
- Replaced stable sorting with unstable sorting of edits returned by the
LSP.
Closes#48812
## Summary
`editor::SplitSelectionIntoLines` currently triggers autoscroll and can
jump to the end of a long file.
This PR makes the action explicitly no-scroll.
## What changed
- Disabled autoscroll in the `unfold_ranges` call inside
`split_selection_into_lines`.
- Switched selection update to `SelectionEffects::no_scroll()`.
## Testing
- Added `test_split_selection_into_lines_does_not_scroll`.
### Screenshots:
- Before: see issue video
- After:
<img width="2486" height="1299" alt="image"
src="https://github.com/user-attachments/assets/8408a2f1-7dd7-4984-aa89-927d5a588322"
/>
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
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Stop scrolling on `editor::SplitSelectionIntoLines` called in the long
files
Fix a bug in the editor's handling of the
`multi_buffer::Event::ExcerptsRemoved` event, where the display map's
`folded_buffers` set was not updated according to the list of removed
buffer ids.
Since the `ProjectSearchView` now relies on the
`Editor.has_any_buffer_folded` method in order to decide the state of
the expand/collapse all excerpts button this could lead to a
bug where, after an initial project search, all excerpts would be
collapsed, and performing a new search would leave the button in a wrong
state, as all excerpts from the new search result would be expanded, but
the button would still consider that there were folded excerpts for the
buffers.
Closes#50521
Release Notes:
- Fixed bug in project search where collapsing a single buffer then
performing a new search in the same view, would break the
expand/collapse all button behavior
Closes#45466
Emojis like 🧑✈️ are grapheme clusters formed using zero-width joiners
and variation selectors. Iterating over the string by individual chars
in `highlight_invisibles` breaks these clusters, even though they
represent a single visible character.
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
- [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:
- Zed now supports compound emojis
Removes a bunch of `dbg!`'s from strings in test code. It's annoying
cause these show up in project search, when you are removing
`dbg!(...)`'s after debugging something
Release Notes:
- N/A
Fixes#50245
### Summary :
This PR fixes linked tag renaming when typing . in tag names like
<Table.Headers>...</Table.Headers>.
Previously, linked editing treated . as punctuation (unless a language
explicitly configured it as a linked-edit character), so renaming could
stop syncing at the dot and produce mismatched closing tags.
### What changed
Updated linked-edit input handling to preserve linked edits when the
typed input is exactly ".", even if the active language does not
explicitly include dot in linked_edit_characters.
Added a regression test covering dot typing in linked edits without
language override.
Kept existing punctuation behavior (e.g. >) unchanged.
### Files changed
[editor.rs]
[editor_tests.rs]
### Why this approach
Minimal, targeted fix in shared linked-edit path.
Works for .svelte and similar markup contexts where dot-separated
component names are valid in practice.
Avoids requiring every language/extension to add dot config
individually.
### Validation
Manual repro confirmed: opening tag rename with dot now keeps closing
tag synced.
Added test: test_linked_edits_on_typing_dot_without_language_override.
Existing related test remains relevant:
test_linked_edits_on_typing_punctuation.
In cases where sticky headers are enabled, count the number of sticky
headers that would be present when performing `editor:scroll cursor
top`. Take the maximum of that number and `verical_scroll_margin` so
that we don't inadvertently bury the cursor behind the sticky headers.
https://github.com/user-attachments/assets/6d49fe3a-2017-4c76-bd92-c4ec9794f898Closes#48864
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
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- Fixed scroll top behavior when there are more sticky headers than
vertical_scroll_margin
This is pure computation work that is disconnected from main thread
entity state yet it can still block for a couple milliseconds depending
on the file
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Deferred draws previously didn't use a content mask, so you could
horizontally scroll an EP popover all the way out of the containing
pane.
This also affects other UI elements that use the deferred draw system; I
think in practice it doesn't make much difference because most of those
seem to require something in the editor to be hovered, so if you scroll
horizontally the element goes away.
Release Notes:
- Fixed being able to scroll the edit prediction popover out of the
containing pane.
This does not yet allow for finding task <-> entity cycles
unfortunately, but at least it does catch entity <-> entity cycles for
the time being
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Release Notes:
- Fixed multiple language servers applying to the same buffer
overwriting each others inlay hints
- Fixed multiple language servers applying to the same multibuffer
discarding each others inlay hints
- Fixed a bug that caused some inlay hints to sometimes duplicate
## Summary
- Tighten `link_pattern_file_candidates` regex from `\(([^)]*)\)` to
`]\(([^)]*)\)` so only Markdown link syntax `[title](path)` triggers
path extraction from parentheses
- Prevents function call arguments like `do_work(file2)` from being
incorrectly resolved as file paths, which preempted LSP go-to-definition
Closes#48938
## Test plan
- [x] `cargo test -p editor hover_links` — all 12 tests pass
- [x] New unit tests verify: function calls don't extract arguments as
file candidates; Markdown links still extract correctly
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Release Notes:
- Fixed Cmd+click navigating to file instead of definition in certain
cases
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Paving the way to remove `ExcerptId`. Done in this PR:
- Unshipped the stack trace view
- Get rid of `push_excerpts`
- Get rid of some callers of `remove_excerpts`
We still need to remove some calls to `remove_excerpts` and other APIs,
especially in `randomly_edit_excerpts` and collaboration.
Release Notes:
- The stack trace multibuffer view has been removed.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
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.
Full line selections should only include the next line if there's a
single line selected. Otherwise, if multiple lines are selected, only
the selected lines should be joined.
Also updates the editor tests to include both of these cases.
Closes#48030
Release Notes:
- Fixed `editor::JoinLines` when a multi-line selection includes the end
of the final line
When `row_infos.is_empty()` (if you have very very tiny editors) we
could
end up trying to read the first item out of it.
Fixes ZED-5AT
Fixes ZED-54F
Fixes ZED-56N
Updates #49260
cc @Veykril
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:
- Fixed a panic rendering diff hunk headers in 0-height editors
These tend to be very often mutated while we don't really need the
subtree sharing of TreeMaps, so replacing them here is generally
cheaper.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
Co-authored by: John Tur <jtur@zed.dev>
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
We were resolving inlay hints against an old snapshot, which
occasionally led to panics
Co-Authored-By: Cole <cole@zed.dev>
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:
- Fixed a (rare) panic in inlay hints
Co-authored-by: Cole <cole@zed.dev>
When copying multiple selections with copy-and-trim, create a single
clipboard selection spanning the original buffer range rather than one
selection per trimmed line. This preserves correct paste behavior in Vim
mode when pasting trimmed content.
Closes#48869.
Release Notes:
- Fixed clipboard selection range for multi-line copy-and-trim
---------
Co-authored-by: dino <dinojoaocosta@gmail.com>
This makes the "Open File" button in the file header within multibuffers
also visible as you hover over the headers. Previously, this button
would only show up for the selected/focused file, but it now also shows
up on hover for making mouse-based interaction easier.
Release Notes:
- N/A
Closes#40602
### Summary
This PR ensures that active debug lines only open in a single pane and
new active debug lines are added to the most recent pane that contained
an active debug line. This fixes a bug where Zed could go to the active
debug line file and location in every pane a user had open, even if that
pane was focused on a different file.
I fixed this by storing the `entity_id` of the pane containing the most
recently active debug line on `BreakpointStore`, this is consistent with
where the selected stack frame is stored. I used an `entity_id` instead
of a strong type to avoid circular dependencies. Whenever an active
debug line is being set in the editor or by the debugger it now checks
if there's a specific pane it should be set in, and after setting the
line it updates `BreakpointStore` state.
I also added a new method on the `workspace::Item` trait called `fn
pane_changed(&mut self, new_pane_id: EntityId, cx: &mut Context<Self>)`
To enable `Editor` to update `BreakpointStore`'s active debug line pane
id whenever an `Editor` is moved to a new pane.
### PR review TODO list
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
- [x] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
Release Notes:
- debugger: Fix bug where active debug lines could be set in the wrong
pane
Fixes ZED-54X
Release Notes:
- Linux: wait to request a graphics context until we have a window so we
can (ideally) pick a better context or (less ideally) fail more
gracefully.
---------
Co-authored-by: Zed Zippy <234243425+zed-zippy[bot]@users.noreply.github.com>
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