Commit Graph
5172 Commits
Author SHA1 Message Date
Cameron Mcloughlin 37c44cf69f workspace: Add separate "format and save" action (#53710)
Release Notes:

- Added `workspace: format and save` action which always formats,
regardless of settings
2026-04-14 16:20:05 +01:00
saberoueslati 2b141e1b5a editor: Fix selection occurrence highlights during regex buffer search (#52611)
## Context

When using regex buffer search (e.g. `^something`), Zed correctly
navigates only to actual matches. However, navigating to a match selects
the matched text, which triggers the **selection occurrence highlight**
feature. That feature performs a *plain literal* search for the selected
word and highlights all occurrences, including ones that don't satisfy
the regex. The user would see a 4th mid-line occurrence highlighted,
even though `^something` never matched it, this behavior is quite
confusing.

The fix tracks whether the current selection was set by search
navigation via a new `from_search: bool` on `SelectionEffects`. When
`last_selection_from_search` is set and `BufferSearchHighlights` are
active, selection occurrence highlights are suppressed. Making a manual
text selection during an active search clears the flag, restoring normal
occurrence-highlight behavior.

The behavior now matches how VSCode handles this case.

The video below demonstrates the behavior after the fix and shows that
it matches the VSCode behavior now

[Screencast from 2026-03-28
01-33-46.webm](https://github.com/user-attachments/assets/07a005b8-53b1-4abf-93d2-96406f0b6a11)

Closes #52589

## How to Review

Three files changed — read in this order:

1. **`crates/editor/src/editor.rs`** Adds `from_search: bool` to
`SelectionEffects` (with a builder method) and
`last_selection_from_search: bool` to `Editor`.
`selections_did_change()` records the flag from effects.
`prepare_highlight_query_from_selection()` returns `None` early when
both `last_selection_from_search` and active `BufferSearchHighlights`
are set.

2. **`crates/editor/src/items.rs`** `activate_match()` now calls
`.from_search(true)` on its `SelectionEffects` so search-driven
selections are marked at the source.

3. **`crates/search/src/buffer_search.rs`** Regression test
`test_regex_search_does_not_highlight_non_matching_occurrences`:
verifies that after search navigation, `SelectedTextHighlight` is
suppressed and exactly 3 `BufferSearchHighlights` exist; and that after
a manual selection, `SelectedTextHighlight` is restored.

## Self-Review Checklist

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

Release Notes:

- Fixed regex buffer search highlighting non-matching word occurrences
via the selection occurrence highlight feature
2026-04-13 23:25:28 -07:00
daydalekandCopilot 3439f3ba47 editor: Add configurable hover delay (#53504)
follow up #47471 

As described in #47471, we introduced a direction-aware strategy to
improve user experience when interacting with hover popovers. In this
follow-up, we are adding `hover_popover_sticky` and
`hover_popover_hiding_delay` to control whether the feature introduced
in 47471 enabled, and to let users configure the delay to balance
responsiveness . Also `hover_popover_sticky` can now be imported from
`editor.hover.sticky`, as well as `hover_popover_hiding_delay` from
`editor.hover.hidingDelay` in VSCode.


Also this PR adds several tests:
- `test_hover_popover_cancel_hide_on_rehover`: when the cursor returns
to the hover after leaving once within the hiding delay, the hover
should persist while canceling the existing hiding timer.
- `test_hover_popover_enabled_false_ignores_sticky` : when
`hover_popover_enabled` is false, the `hover_popover_sticky` and
`hover_popover_hiding_delay` have no effect(since no hover is shown).
- `test_hover_popover_sticky_delay_restarts_when_mouse_gets_closer`:
when mouse gets closer to hover popover, we expect the timer to reset
and the hover remains visible.
- `test_hover_popover_hiding_delay`: check if the delay(in test, that's
500ms) works.
- `test_hover_popover_sticky_disabled`: when hover_popover_sticky is
false, the hover popover disappears immediately after the cursor leaving
the codes.
- VSCode import test in `settings_store.rs`

Release Notes:

- Added `hover_popover_sticky` and `hover_popover_hiding_delay` settings
to balance responsiveness of hover popovers.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-13 09:46:19 +03:00
João Soares a02da73df4 editor: Fix semantic tokens missing when opening buffer from multibuffer (#53712)
Summary

Semantic token highlighting was missing when opening a file from
multibuffer search results (Ctrl+Shift+F). Which file got hit depended
on window size and scroll offset.

## Root cause

Two async tasks race to write `post_scroll_update`:

1. `set_visible_line_count` (scroll.rs:682) fires on first render and
spawns a task that calls `register_visible_buffers` + `update_lsp_data`
(requests semantic tokens).

2. `open_buffers_in_workspace` (editor.rs:25049) calls
`change_selections` with autoscroll right after creating the editor.
This emits `ScrollPositionChanged`, whose handler (editor.rs:2655)
replaces `post_scroll_update` with a task calling
`update_data_on_scroll`.

3. `update_data_on_scroll` (editor.rs:26099) has a singleton guard: `if
!self.buffer().read(cx).is_singleton()` that skips `update_lsp_data` for
single-file buffers. This is a scroll optimization, singleton buffers
don't change their visible buffer set on scroll.

4. The initial task gets dropped, the replacement skips
`update_lsp_data`, semantic tokens are never requested.

## Fix

Added a `needs_initial_lsp_data` flag to the Editor struct, set to
`true` on creation. `update_data_on_scroll` checks this flag alongside
the singleton guard, so `update_lsp_data` runs at least once even for
singletons. The flag flips to `false` right after, so subsequent scrolls
behave exactly as before. No perf impact after the first render.

## Self-review checklist

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

Closes #53051

## Demo

Before:

https://github.com/user-attachments/assets/77d07d95-cb4a-44ff-842d-1f7a46653ca9
After:


https://github.com/user-attachments/assets/2c942f52-4ec3-459f-a97b-93919e4bfb3d



## Release notes

- Fixed semantic token highlighting missing when opening a buffer from
multibuffer search results
2026-04-12 22:00:40 +03:00
Smit Chaudhary b5f31b0dc4 editor: Fix breadcrumb syntax colors not updating when theme changes (#53185) 2026-04-11 16:52:27 +00:00
Kirill Bulatov 7aa14f5d31 Add settings and disable mouse wheel zoom by default (#53622)
Follow-up of https://github.com/zed-industries/zed/pull/53452

Release Notes:

- N/A
2026-04-10 12:34:50 +00:00
Kirill Bulatov 0bba730c1e Restrict mouse wheel zoom for certain editors (#53598)
Follow-up of https://github.com/zed-industries/zed/pull/53452

* disables mouse wheel zooming in agent, debugger, keymap editor, dev
inspector and repl-related editors
* adjusts the code to call for theme changes directly instead of sending
the events, so that agent following does not capture the events and
changes its font size

Release Notes:

- N/A
2026-04-10 09:20:38 +00:00
Sean HagstromandDmitry Soluyanov 74a2a34147 editor: Add Ctrl+scroll wheel zoom for buffer font size (#53452)
Closes https://github.com/zed-industries/zed/pull/53452

Release Notes:

- Add event handling on editor to increase/decrease font-size when using
the scroll-wheel and holding the secondary modifier (Ctrl on
Linux/Windows, and Cmd on macOS)

Screen Capture:


https://github.com/user-attachments/assets/bf298be4-e2c9-470c-afef-b7e79c2d3ae6

---------

Co-authored-by: Dmitry Soluyanov <dimitri.soluyanov@yandex.ru>
2026-04-09 12:10:39 +03:00
ozacodandozacod 267ab24cfb editor: Add action to toggle block comments (#48752)
Closes #4751

## Testing
- Manually tested by comparing the behaviors with vscode.
- Those requirements are added to unit tests.

Release Notes:

- Added action to toggle block comments

---------

Co-authored-by: ozacod <ozacod@users.noreply.github.com>
2026-04-08 22:29:16 +03:00
Kirill Bulatov 7bf10f4bc0 Stop highlighting selection matches in the search inputs (#53307)
Follow-up of https://github.com/zed-industries/zed/pull/52553

Restores previous search inputs' behavior where no extra highlights were
applied.

Before:


https://github.com/user-attachments/assets/38b6e70c-d5d5-4e06-abec-97d20af44f39

After: 


https://github.com/user-attachments/assets/6e4b3931-adf0-4c2a-afc3-f3c839fc9add


Release Notes:

- N/A
2026-04-07 19:17:49 +03:00
Xin ZhaoandKirill Bulatov e950abb32b editor: Fix diagnostic rendering when semantic tokens set to full (#53008)
Self-Review Checklist:

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

Closes #50212

There are two unreasonable coupling account for this issue, the coupling
of `use_tree_sitter` with `languge_aware` in

https://github.com/zed-industries/zed/blob/ca8bd8681c123b995b495a79d760bc0d88220fd0/crates/editor/src/element.rs#L3820-L3822
and the coupling of `language_aware` with `diagnostics` in
https://github.com/zed-industries/zed/blob/ca8bd8681c123b995b495a79d760bc0d88220fd0/crates/language/src/buffer.rs#L3736-L3746

Because of these couplings, when the editor stops using Tree-sitter
highlighting when `"semantic_tokens"` set to `"full"`, it also
accidentally stops fetching diagnostic information. This is why error
and warning underlines disappear.

I’ve fixed this by adding a separate `use_tree_sitter` parameter to
`highlighted_chunks`. This way, we can keep `language_aware` true to get
the diagnostic data we need, but still decide whether or not to apply
Tree-sitter highlights. I chose to fix this at the `highlighted_chunks`
level because I’m worried that changing the logic in the deeper layers
of the DisplayMap or Buffer might have too many side effects that are
hard to predict. This approach feels like a safer way to solve the
problem.

Release Notes:

- Fixed a bug where diagnostic underlines disappeared when
"semantic_tokens" set to "full"

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-04-07 14:15:33 +00:00
Ahmet Kaan GümüşandConrad Irwin 73426713f2 markdown_preview: Add search support to markdown preview (#52502)
Context

The markdown preview had no search functionality — pressing Ctrl+F did
nothing. This PR implements the SearchableItem trait for
MarkdownPreviewView, enabling in-pane text search with match
highlighting and navigation.

  Changes span four crates:

- project: Added SearchQuery::search_str() — a synchronous method to
search plain &str text, since the existing search() only works on
BufferSnapshot.
- markdown: Added search highlight storage to the Markdown entity and
paint_search_highlights to MarkdownElement. Extracted the existing
selection painting into a reusable paint_highlight_range helper to avoid
duplicating quad-painting logic.
- markdown_preview: Implemented SearchableItem with full match
navigation, active match tracking, and proper SearchEvent emission
matching Editor behavior.
- Keymaps: Added buffer_search::Deploy bindings to the MarkdownPreview
context on all three platforms.
  
The PR hopefully Closes
https://github.com/zed-industries/zed/issues/27154

  How to Review

1. crates/project/src/search.rs — search_str method at the end of impl
SearchQuery. Handles both Text (AhoCorasick) and Regex variants with
whole-word and multiline support.
  2. crates/markdown/src/markdown.rs — Three areas:
    - New fields and methods on Markdown struct (~line 264, 512-548)
- paint_highlight_range extraction and paint_search_highlights (~line
1059-1170)
    - The single-line addition in Element::paint (~line 2003)
3. crates/markdown_preview/src/markdown_preview_view.rs — The main
change. Focus on:
- SearchEvent::MatchesInvalidated emission in schedule_markdown_update
(line 384)
    - EventEmitter<SearchEvent> and as_searchable (lines 723, 748-754)
- The SearchableItem impl (lines 779-927), especially active_match_index
which computes position from old highlights to handle query changes
correctly
  4. Keymap files — Two lines each for Linux/Windows, one for macOS.

  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)
- [ x ] The content is consistent with the [UI/UX
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)
(should be 😄 )
- [ - ] Tests cover the new/changed behavior (not sure)
- [ - ] Performance impact has been considered and is acceptable (I'm
not sure about it and it would be nice to see experienced people to
test)


Release Notes:
- Added search support (Ctrl+F / Cmd+F) to the markdown preview

---------

Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2026-04-06 16:42:20 +00:00
DinoandYara 2dc96a7c92 Update futures to 0.3.32 (#52910)
As part of the work that is being developed for the Project Panel's Undo
& Redo system, in
https://github.com/zed-industries/zed/tree/5039-create-redo , we're
implementing an asynchronous task queue which simply receives a message
with the operation/change that is meant to be carried out, in order to
ensure these run in a sequential fashion.

While trying to use `futures_channel::mpsc::Receiver`, it was noted that
`recv` method was not available so this Pull Request updates the
`futures` crate to `0.3.32`, where it is available.

This version also deprecates `try_next` in favor of `try_recv` so this
Pull Request updates existing callers of `try_next` to use `try_recv`,
which was mostly updating the expected return type from
`Result<Option<T>>` to `Result<T>`.

Co-authored-by: Yara <git@yara.blue>
2026-04-05 23:05:35 +01:00
451dcd192a Fix resolution of multibuffer anchors that lie outside excerpt boundaries (#53118)
It's possible to create a multibuffer anchor that points into a specific
excerpted buffer (so not min/max), but whose main buffer `text::Anchor`
isn't contained in any of the excerpts for that buffer. When summarizing
such an anchor, we map it to the multibuffer position of the start of
the next excerpt after where the anchor "should" appear. Or at least,
that's the intention, but it turned out we had some bugs in
`summary_for_anchor` and `summaries_for_anchors` that caused them to
return bizarre summaries for these anchors. This PR fixes that and also
updates `test_random_multibuffer` to actually test
`MultiBufferSnapshot::summary_for_anchor` against a reference
implementation, including for out-of-bounds anchors.

Self-Review Checklist:

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

Release Notes:

- N/A

---------

Co-authored-by: Anthony <anthony@zed.dev>
Co-authored-by: Max <max@zed.dev>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
2026-04-04 00:16:11 -04:00
Kirill Bulatov 5f04b7453d Fixup and test edit prediction mocks (#52991)
Follow-up of https://github.com/zed-industries/zed/pull/40185

Release Notes:

- N/A
2026-04-02 15:53:37 +02:00
Finn EversandKirill Bulatov 123a29795d language_core: Introduce fallback highlights (#52575)
Self-Review Checklist:

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

Release Notes:

- Added the option for highlights from languages to specify fallbacks.
That means that if you have a pattern with the captures `@second.capture
@first.capture`, Zed will first try resolving a highlight from your
theme for the code fragment using the first capture, then look for the
second capture if no match for the first capture could be found.

---------

Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-04-02 12:52:42 +00:00
Xin Zhao 05b69cef68 editor: Support disabling semantic token highlighting via empty rules (#52963)
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 #52882, should help #52723

According to the [Zed
documentation](https://zed.dev/docs/semantic-tokens#example-disabling-a-token-type),
users should be able to disable semantic highlighting for a specific
token type by adding an empty rule in `settings.json`.

However, the current implementation fails to respect this because its
merging logic allows lower-priority default styles to "leak through"
even when a matching high-priority rule is empty. This makes it
impossible to selectively disable semantic tokens to reveal the
underlying Tree-sitter highlighting when using "semantic_tokens":
"combined". This is particularly problematic for extensions that provide
specialized Tree-sitter queries which are currently being obscured by
less desirable semantic tokens(#52723).

This PR fixes the logic to ensure that a completely empty high-priority
rule acts as an opaque override, correctly disabling semantic styling
for that token type and allowing Tree-sitter highlighting to show
through as intended.

Release Notes:

- Fixed a bug where semantic token highlighting could not be disabled
via empty rules in `settings.json`.
2026-04-02 06:43:16 +00:00
Conrad IrwinandCole Miller 1d8c8786dc Fix an ordering problem that led to invalid edits in display map sync (#52930)
Co-authored-by: Cole Miller <cole@zed.dev>

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

Fixes ZED-67X
Fixes ZED-50E

Release Notes:

- N/A

Co-authored-by: Cole Miller <cole@zed.dev>
2026-04-01 16:04:58 -06: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
Tim Vermeulen f45c9c8579 editor: Prevent blame popover from appearing when cursor is on different pane (#52603)
The blame popover shouldn't appear when the cursor hovers over the
annotation but on a different pane.

Before:


https://github.com/user-attachments/assets/dbf6f7b5-e27f-495b-8d6f-fa75a4feee18

After:


https://github.com/user-attachments/assets/d5e186df-4ebf-4b4c-bb5f-4d9e7b0f62c7

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 bug that caused git blame annotations to be hoverable from a
different pane.
2026-04-01 14:41:50 +00:00
Tim Vermeulen cfe8d1ba45 editor: Clear previous select mode when clicking on a sticky header (#52636)
Clicking on a sticky header causes
`selections.select_ranges([anchor..anchor])` to be called, but this does
not clear the editor's `selections.select_mode()`, resulting in possible
incorrect selections if this is followed up by a shift-click. This PR
fixes that with
```diff
- selections.select_ranges([anchor..anchor]);
+ selections.clear_disjoint();
+ selections.set_pending_anchor_range(anchor..anchor, SelectMode::Character);
```
which is essentially what `editor.select(SelectPhase::Begin { ... },
...)` (i.e. a regular single click in the editor) does as well.

Before:


https://github.com/user-attachments/assets/bcf2647e-a22a-4866-8975-d29e135df148

After:


https://github.com/user-attachments/assets/fb82db51-fef1-4b7c-9954-6e076ae0b176

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 bug that caused clicking on a sticky header to not always
properly clear the previous selection.
2026-04-01 14:29:27 +00:00
416f296d80 markdown: Refactor code block copy button visibility to use enum (#52817)
Release Notes:

- N/A

---------

Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
Co-authored-by: Finn Evers <finn.evers@outlook.de>
Co-authored-by: MrSubidubi <finn@zed.dev>
2026-04-01 09:05:03 +00:00
Tim Vermeulen f38cd30f5c editor: Deduplicate sticky header rows (#52844)
Fixes a bug that caused duplicate sticky header rows to appear if
multiple outline items start on the same row.

Sort of addresses #52722, although arguably the real issue there is that
duplicate outline items are being created in the first place.

Before:


https://github.com/user-attachments/assets/7941cbe8-9b62-470c-b475-f08f2f20fac6

After:


https://github.com/user-attachments/assets/c4e291ea-6414-483f-8ff7-3d89d10000b6

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 a bug that caused duplicate sticky header rows to appear if
multiple outline items start on the same row.
2026-03-31 18:56:49 +00:00
Pratik Karki c784ba5110 Fix FormatSelections to only format selected ranges, not entire document (#51593)
When `editor: format selections` get invoked, the Prettier and external
formatter branches in `format_buffer_locally` ignored the selection
ranges entirely, causing the whole document to be formatted.

- Thread selection ranges as UTF-16 offsets through to Prettier via
`rangeStart/rangeEnd` options in the format request.
- Skip external formatters when ranges are present, since they have no
mechanism for range formatting.
- Create diff edits and apply them for JSON-like languages. For
single-expression languages like JSON, it wasn't respecting the range
commands from Prettier. So, filter the diff edits returned by Prettier
to retain only those overlapping with the user's selection byte ranges,
ensuring changes outside the selection are never applied.

Part of #25796 

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 FormatSelections to only format selected ranges, not the entire
document where prettier is supported.

Current Behaviour:

[original
behaviour.webm](https://github.com/user-attachments/assets/d5f0cb48-4c3f-44aa-89a9-975f31fce92d)

New Behaviour:

[new
behaviour.webm](https://github.com/user-attachments/assets/41e04b90-f37f-43e1-b8ed-4622684454b1)

---------

Signed-off-by: Pratik Karki <pratik@prertik.com>
2026-03-31 12:48:22 +03:00
Ian Chamberlain 628c77b168 editor: Limit CopyHighlightJson to selection (#46555)
Closes https://github.com/zed-industries/zed/issues/36618

I'm not sure if there is a specific issue for this, but I noticed it
while working on some other PRs, as have some other people:
https://github.com/zed-industries/zed/issues/20525#issuecomment-2469507157

Cause: when running `copy highlight JSON` from the command palette,
input was disabled due to the modal, and the selection method call
always returns `None`. This most likely works as expected when bound to
a keyboard shortcut, but since there is no default shortcut most people
probably don't execute this action that way.

Fix: just grab the selection directly; I don't think this command needs
to be IME-aware, so it doesn't need to use `selected_text_range`.

NOTE: There still seems to be an issue where `VISUAL LINE` mode doesn't
select anything, even when I called `selections.newest_adjusted`, so I
opted to try and keep the implementation closest to what it was doing
before. (edit: actually this might just be the same as #45799?).

Release Notes:

- Fixed `editor: copy highlight JSON` not limiting to the current
selection
2026-03-31 08:39:44 +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 OsiewiczandLukas Wirth 1c18a6c497 ui: Follow-up to ui crate teardown (#52747)
- **Remove some of the settings types from ui**
- **drag settings-less ui across the line**

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

---------

Co-authored-by: Lukas Wirth <me@lukaswirth.dev>
2026-03-30 18:04:21 +02:00
Oleksiy Syvokon 05b5089df8 Fix panic in restore_diff_hunks when base text changes async (#52743)
Read base_text from the `MultiBufferSnapshot` instead of the live
`BufferDiff` entity in `prepare_restore_change`. The live entity's
base_text may already reflect a newer git HEAD while the snapshot still
holds old hunk byte ranges, causing `Rope::slice` to panic.

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

Release Notes:

- N/A
2026-03-30 16:57:48 +02:00
HuaGu-Dragon f1ce54cf4b editor: Merge additional completion edits into primary undo transaction (#52699)
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 #45986

Release Notes:

- Fixed postfix snippets now creating 1 `undo` actions instead of 2.
2026-03-30 11:13:07 +00:00
f633c54cf8 editor: Fix LSP extension commands failing at end of file (#52651)
## Context

Closes #51330

When the cursor is at the very end of a file,
`find_specific_language_server_in_selection` in
`crates/editor/src/lsp_ext.rs` silently skips the selection because the
anchor's `buffer_id` is `None`. This causes `editor: switch source
header` (clangd) and rust-analyzer extension commands (`expand macro`,
`open docs`, `open playground`) to do nothing.

The fix falls back to the singleton buffer's ID when the anchor has no
`buffer_id`.

## How to Review

Single file change in `crates/editor/src/lsp_ext.rs`. The diff is small
— pre-compute the singleton buffer ID, then use it as fallback in the
`filter_map` closure. An integration test verifies the fix.

## Self-Review Checklist

- [x] Reviewed own diff for quality, security, and reliability
- [x] No unsafe blocks
- [x] Tests pass (639 editor tests, 0 failures)
- [x] Manual testing: switch source header works at beginning, middle,
and end of C++ file

## Test Plan

- [x] New integration test: `test_find_language_server_at_end_of_file` —
verifies `find_specific_language_server_in_selection` returns `Some` at
both beginning and end of file
- [x] Confirmed the test fails without the fix (assertion on "should
find language server at end of file")
- [x] Manual: open a C++ file with clangd, place cursor at very end, run
`switch source header` — now correctly opens the header
- [x] Manual: verify it still works at beginning and middle of file
(non-regression)
- [x] `cargo test -p editor` — 639 passed, 0 failed

Release Notes:

- Fixed `editor: switch source header` and other LSP extension commands
not working when the cursor is at the very end of a file.

---------

Co-authored-by: Florian Trehaut <florian.trehaut@hillcode.fr>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-03-30 11:12:32 +00:00
Yao XiaoandMrSubidubi c75269f8cb agent_ui: Fix expanded message editor jitters while typing (#52612)
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 #52132.

*This PR previously also fixes the "expanded message editor not taking
up full height" part, but #52545 has already fixed that. Yet it seems to
leave a new issue (that was previously not revealed) behind, as
follows.*

This PR fixes the `Full + ExcludeOverscrollMargin` editor mode (which
the agent panel message editor uses in expanded mode), which could
jitter while typing because render-time layout and scroll-position
updates were clamping against different effective
`scroll_beyond_last_line` policies. This PR fixes that inconsistency so
the expanded editor stays stable while typing, and adds a regression
test covering `ExcludeOverscrollMargin` scroll clamping.


https://github.com/user-attachments/assets/86abf04d-c1a1-419b-96d0-8ca097c0acb0


https://github.com/user-attachments/assets/03dbdc3c-f58e-4378-8c6a-4bda1ae425c8

Release Notes:

- Fixed the expanded Agent Panel message editor so it no longer jitters
while typing.

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-03-30 08:19:09 +00:00
Max Brunsfeld 577c9909fa Fix crash when LSP returns multiple nested definition ranges (#52701)
This fixes a crash when navigating to multiple definitions in a
singleton buffer (https://github.com/zed-industries/zed/pull/51461).

Release Notes:

- N/A
2026-03-30 09:34:29 +02:00
Lukas Wirth 6d33fa6b71 Make paste a separate undo transaction from preceding edits (#52003)
When undoing a paste, it is really confusing when that actually also
removes what was type right before the paste if the paste happened fast
enough after.

Release Notes:

- Fixed undoing a paste sometimes also undoing edits right before the
paste
2026-03-30 07:17:02 +00:00
Mikayla Maki b1415bcdc6 Strong app state (#52602)
This PR upgrades the workspace's app state to a strong pointer. It's an
app-global concern, and it should only die when the app dies. When the
app dies the process exits, so the cyclic reference problem isn't an
issue.

Self-Review Checklist:

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

Release Notes:

- N/A
2026-03-27 14:56:46 -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
Ben Vollrathanddino e0872de219 editor: Autoscroll to initial selection on select all matches edit (#49232)
Fix the way selections are built in `Editor::select_all_matches` in
order to guarantee that the original selection, where the user's cursor
is located, is the last selection provided to
`MutableSelectionsCollection::select_ranges` as the editor will attempt
to scroll to the last selection when the user starts editing.

This way, we ensure that the user stays in the same location from which
the `editor: select all matches` action was triggered when they start
editing.

Closes #32894

Release Notes:

- Fixed an issue where editing selections after `editor: select all
matches` would scroll to the last match

---------

Co-authored-by: dino <dinojoaocosta@gmail.com>
2026-03-27 10:44:46 +00:00
Lukas Wirth c823c086be Cut fs dependency from theme (#52482)
Trying to clean up the deps here for potential use of the ui crate in
web

Release Notes:

- N/A or Added/Fixed/Improved ...
2026-03-27 08:17:30 +00:00
Shuhei KadowakiandMrSubidubi 90dae1f042 editor: Fix fade_out styling for completion labels without highlights (#45936)
LSP's `CompletionItemKind` is defined by the protocol and may not have a
corresponding highlight name in a language's `highlights.scm`. For
example, Julia's grammar defines `@function.call` but not `@function`,
so completions with `Method` kind cannot resolve a highlight. Since the
mapping from `CompletionItemKind` to highlight names is an internal
implementation detail that is not guaranteed to be stable, the fallback
behavior should provide consistent styling regardless of grammar
definitions.

Bundled language extensions (e.g., Rust, TypeScript) apply `fade_out` or
muted styling to the description portion of completion labels, so the
fallback path and extension-provided labels should match this behavior.

Previously, the description portion could fail to receive the expected
`fade_out` styling in several independent cases:

1. When `runs` was empty (grammar lacks the highlight name), the
`flat_map` loop never executed
2. When theme lacked a style for the `highlight_id`, early return
skipped the `fade_out` logic
3. When extensions used `Literal` spans with `highlight_name: None`,
`HighlightId::default()` was still added to `runs`, preventing
`fade_out` from being applied

The fix ensures description portions consistently receive `fade_out`
styling regardless of whether the label portion can be highlighted, both
for fallback completions and extension-provided labels.

Closes #ISSUE

Release Notes:

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

---------

Co-authored-by: MrSubidubi <finn@zed.dev>
2026-03-26 11:33:36 +01:00
ab3697f163 Extract language_core and grammars crates from language (#52238)
This extracts a `language_core` crate from the existing `language`
crate, and creates a `grammars` data crate. The goal is to separate
tree-sitter grammar infrastructure, language configuration, and LSP
adapter types from the heavier buffer/editor integration layer in
`language`.

## Motivation

The `language` crate pulls in `text`, `theme`, `settings`, `rpc`,
`task`, `fs`, `clock`, `sum_tree`, and `fuzzy` — all of which are needed
for buffer integration (`Buffer`, `SyntaxMap`, `Outline`,
`DiagnosticSet`) but not for grammar parsing or language configuration.
Extracting the core types lets downstream consumers depend on
`language_core` without pulling in the full integration stack.

## Dependency graph after extraction

```
language_core   ← gpui, lsp, tree-sitter, util, collections
grammars        ← language_core, rust_embed, tree-sitter-{rust,python,...}
language        ← language_core, text, theme, settings, rpc, task, fs, ...
languages       ← language, grammars
```

## What moved to `language_core`

- `Grammar`, `GrammarId`, and all query config/builder types
- `LanguageConfig`, `LanguageMatcher`, bracket/comment/indent config
types
- `HighlightMap`, `HighlightId` (theme-dependent free functions
`highlight_style` and `highlight_name` stay in `language`)
- `LanguageName`, `LanguageId`
- `LanguageQueries`, `QUERY_FILENAME_PREFIXES`
- `CodeLabel`, `CodeLabelBuilder`, `Symbol`
- `Diagnostic`, `DiagnosticSourceKind`
- `Toolchain`, `ToolchainScope`, `ToolchainList`, `ToolchainMetadata`
- `ManifestName`
- `SoftWrap`
- LSP data types: `BinaryStatus`, `ServerHealth`,
`LanguageServerStatusUpdate`, `PromptResponseContext`, `ToLspPosition`

## What stays in `language`

- `Buffer`, `BufferSnapshot`, `SyntaxMap`, `Outline`, `DiagnosticSet`,
`LanguageScope`
- `LspAdapter`, `CachedLspAdapter`, `LspAdapterDelegate` (reference
`Arc<Language>` and `WorktreeId`)
- `ToolchainLister`, `LanguageToolchainStore` (reference `task` and
`settings` types)
- `ManifestQuery`, `ManifestProvider`, `ManifestDelegate` (reference
`WorktreeId`)
- Parser/query cursor pools, `PLAIN_TEXT`, point conversion functions

## What the `grammars` crate provides

- Embedded `.scm` query files and `config.toml` files for all built-in
languages (via `rust_embed`)
- `load_queries(name)`, `load_config(name)`,
`load_config_for_feature(name, grammars_loaded)`, and `get_file(path)`
functions
- `native_grammars()` for tree-sitter grammar registration (behind
`load-grammars` feature)

## Pre-cleanup (also in this PR)

- Removed unused `Option<&Buffer>` from
`LspAdapter::process_diagnostics`
- Removed unused `&App` from `LspAdapter::retain_old_diagnostic`
- Removed `fs: &dyn Fs` from `ToolchainLister` trait methods
(`PythonToolchainProvider` captures `fs` at construction time instead)
- Moved `Diagnostic`/`DiagnosticSourceKind` out of `buffer.rs` into
their own module

## Backward compatibility

The `language` crate re-exports everything from `language_core`, so
existing `use language::Grammar` (etc.) continues to work unchanged. The
only downstream change required is importing `CodeLabelExt` where
`.fallback_for_completion()` is called on the now-foreign `CodeLabel`
type.

Release Notes:

- N/A

---------

Co-authored-by: Agus Zubiaga <agus@zed.dev>
Co-authored-by: Tom Houlé <tom@tomhoule.com>
2026-03-25 23:41:09 +00:00
87cf3317e4 language: Improve highlight map resolution (#52183)
This PR refactors the highlight map capture name resolution to be faster
and more predictable. Speficically,
- it changes the capture name matching to explicit prefix matching
(e.g., `function.call.whatever.jsx` will now be matched by only
`function`, `function.call`, `function.call.whatever` and
`function.call.whatever.jsx`). This matches the behavior VSCode has
- resolving highlights is now much more efficient, as we now look up
captures in a BTreeMap as opposed to searching in a Vector for these.

This substantially improves the performance for resolving capture names
against themes. With the benchmark added here for creating the
HighlightMap, we see quite some improvements:
```
Running benches/highlight_map.rs (target/release/deps/highlight_map-f99da68650aac85b)
HighlightMap::new/small_captures/small_theme
                        time:   [161.90 ns 162.70 ns 163.55 ns]
                        change: [-39.027% -38.352% -37.742%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild
HighlightMap::new/small_captures/large_theme
                        time:   [231.37 ns 233.02 ns 234.70 ns]
                        change: [-91.570% -91.516% -91.464%] (p = 0.00 < 0.05)
                        Performance has improved.
HighlightMap::new/large_captures/small_theme
                        time:   [991.82 ns 994.94 ns 998.50 ns]
                        change: [-50.670% -50.443% -50.220%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  5 (5.00%) high mild
HighlightMap::new/large_captures/large_theme
                        time:   [1.6528 µs 1.6650 µs 1.6784 µs]
                        change: [-91.684% -91.637% -91.593%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) low mild
```

For large themes and many capture names, the revised approach is much
faster.

With that in place, we can also add better fallbacks whenever we change
tokens, since e.g. a change from `@variable` to `@preproc` would
previously cause tokens to not be highlighted at all, whereas now we can
add fallbacks for such cases more efficiently. I'll add this later on to
this PR.


## Self-Review Checklist

<!-- Check before requesting review: -->
- [X] I've reviewed my own diff for quality, security, and reliability
- [ ] Unsafe blocks (if any) have justifying comments
- [ ] 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 resolution speed of theme highlight capture names. This might
change highlighting in some rare edge cases, but should overall make
highlighting more predicatable. Theme captures will now follow a strict
prefix matching, so e.g. function.call.decorator.jsx` will now be
matched by only `function`, `function.call`, `function.call.decorator`
and `function.call.decorator.jsx` with the most specific capture always
taking precedence.

---------

Co-authored-by: Piotr Osiewicz <24362066+osiewicz@users.noreply.github.com>
Co-authored-by: Gaauwe Rombouts <mail@grombouts.nl>
2026-03-25 17:01:17 +01:00
ef282cca24 Add vim/emacs modeline support (#49267)
Many editors such as vim and emacs support "modelines", a comment at the
beginning of the file that allows the file type to be explicitly
specified along with per-file specific settings

- The amount of configurations, style and settings mapping cannot be
handled in one go, so this opens up a lot of potential improvements.
- I left out the possiblity to have "zed" specific modelines for now,
but this could be potentially interesting.
- Mapping the mode or filetype to zed language names isn't obvious
either. We may want to make it configurable.

This is my first contribution to zed, be kind. I struggled a bit to find
the right place to add those settings. I use a similar approach as done
with editorconfig (merge_with_editorconfig). There might be better ways.

Closes #4762

Release Notes:

- Add basic emacs/vim modeline support.

Supersedes #41899, changes:
- limit reading to the first and last 1kb
- add documentation
- more variables handled
- add Arc around ModelineSettings to avoid extra cloning
- changed the way mode -> language mapping is done, thanks to
`modeline_aliases` language config
- drop vim ex: support
- made "Local Variables:" handling a separate commit, so we can drop it
easily
- various code style improvements

---------

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
2026-03-25 03:15:51 +00:00
Ignacio dad8f9d5b3 workspace: Deduplicate navigation history entries (#44504)
Closes #43545

Remove existing entries for an item before adding new ones to the
navigation history. This prevents Go Back (Ctrl-O) from bouncing between
the same items repeatedly.

Navigation pattern A->B->A->B->C now creates history [A,B,C] instead of
[A,B,A,B,C], making backward navigation more efficient.

Release Notes:

- N/A
2026-03-24 20:13:44 -06:00
Ben Kunkle 3f482fb20e ep: Only report shown once prediction is previewed in subtle mode (#52362)
## Context

We currently mark the current prediction as "shown" when the subtle mode
indicator appears. This doesn't really make sense. We make an effort
elsewhere to differentiate between a user rejecting a prediction that
they viewed vs. never saw in order to compute accurate metrics.

## 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 or Added/Fixed/Improved ...
2026-03-24 19:35:48 -04:00
Ben Kunkle 64a02d0e8f Don't keep stale predictions in if they were discarded (#52334)
## Context

We're seeing issues where discarding a prediction (e.g. `editor::Cancel`
while a prediction is being shown) seems to just hide it temporarily.
This is becoming a larger issue with #51842 as we now expect people to
be dismissing predictions in order to insert literal tabs in certain
contexts.
The logic changed in this PR is part of the problem, but the model
generating the same prediction multiple times is also likely
contributing. That will be solved as-needed later.


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

- Fixed an issue where dismissing an edit prediction would not fully
discard it, causing it to re-appear
2026-03-24 14:09:02 -04:00
João Soares 6e5b52ca47 editor: Include closing delimiter on same line when folding (#50090)
CLOSES: #50002 

When using indent-based folding (the default, `document_folding_ranges =
Off`),
collapsed folds in brace-delimited languages displayed the closing
delimiter on
a separate line:

fn b() {⋯
}

This extends the fold range in `crease_for_buffer_row` to include the
trailing
newline and leading whitespace before a closing `}`, `)`, or `]`,
producing
the expected single-line display:

fn b() {⋯}

Whitespace-sensitive languages like Python are unaffected — their
terminating
lines don't start with a closing delimiter, so the existing behavior is
preserved.

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)

Screenshots:
Before:
<img width="676" height="584" alt="image"
src="https://github.com/user-attachments/assets/0779233b-e287-495a-bab4-d2a97829e1c0"
/>


After:
<img width="1498" height="824" alt="image"
src="https://github.com/user-attachments/assets/ec6b4cb0-dac1-4db0-beed-38131a27b5c8"
/>



Release Notes:

- Fixed indent-based code folding to display the closing delimiter (`}`,
`)`, `]`) on the same line as the fold placeholder instead of on a
separate line
([#50002](https://github.com/zed-industries/zed/issues/50002)).
2026-03-24 18:08:43 +02:00
d943b16990 project: Fix code_actions_on_format edits being reverted when no formatter available (#51605)
Fixes #51490

## Problem

When `code_actions_on_format` is configured (e.g.,
`source.fixAll.phpcs`) and `formatter` is not explicitly set, code
action edits are applied but then reverted during format-on-save.

The root cause is in the formatting pipeline's error handling. Code
actions and formatters share a single transaction via `.chain()`. When
`Formatter::Auto` resolves to `Formatter::Prettier` (PHP defaults to
`prettier.allowed: true`), and prettier is not installed or fails, the
error propagates via `?` out of the formatter loop, aborting the entire
`format_buffer_locally` function. This causes the formatting transaction
- which already contains the successfully applied code action edits - to
be lost.

The workaround of setting `"formatter": []` works because it removes all
formatters from the chain, so no formatter can fail and trigger the
abort.

## Fix

Change error handling for individual formatters (Prettier, External
command, Language Server) from propagating errors via `?` to logging the
error and continuing to the next formatter. This treats "formatter
failed" as a no-op for that specific formatter rather than aborting the
entire pipeline.

This matches the existing pattern used when `LanguageServer(Current)`
finds no server that supports formatting - it already logs and
`continue`s rather than erroring.

## Testing

- `cargo check -p project` passes
- `cargo fmt -p project -- --check` passes

Release Notes:

- Fixed `code_actions_on_format` edits being reverted when `formatter:
"auto"` resolves to an unavailable formatter.

---------

Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
2026-03-23 14:33:35 +00:00
Dino c0da60901a helix: Add support for line length in reflow command (#52152)
* Add `editor::RewrapOptions::line_length` to, optionally, override the
  line length used when rewrapping text.
* Update `editor::Editor::rewrap_impl` to prefer
  `editor::RewrapOptions::line_length`, when set.
* Add a `line_length` field to the `vim::rewrap::Rewrap` action.
* Update the `:reflow` vim command with `vim::command::VimCommand::args`
  so as to be able to parse the provided argument as `usize`, ensuring
  that no effect is taken if the argument can't be parsed as such.

Release Notes:

- N/A
2026-03-23 11:09:54 +00:00
Ben Kunkle 3f95740d26 Fix regression preventing new predictions from being previewed in subtle mode (#51887)
## Context

<!-- What does this PR do, and why? How is it expected to impact users?
     Not just what changed, but what motivated it and why this approach.

Link to Linear issue (e.g., ENG-123) or GitHub issue (e.g., Closes #456)
     if one exists — helps with traceability. -->
Fixes some issues with https://github.com/zed-industries/zed/pull/51842
Namely that the tests were scattered and not well organized (this PR
also makes them more thorough), and a regression where holding the
modifiers for the accept prediction keybind would not cause an incoming
prediction to be immediately previewed.

## How to Review

<!-- Help reviewers focus their attention:
- For small PRs: note what to focus on (e.g., "error handling in
foo.rs")
- For large PRs (>400 LOC): provide a guided tour — numbered list of
files/commits to read in order. (The `large-pr` label is applied
automatically.)
     - See the review process guidelines for comment conventions -->

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

- (Preview v0.229.x only) Fixed a regression where holding the modifiers
for the accept edit prediction keybind would not immediately preview
predictions as they arrived
2026-03-23 00:20:55 -04:00
Kai Kozlov a88bcd3714 Fix incorrect rainbow bracket matching in Markdown (#52107)
## Context

Fixes #52022.

Rainbow bracket matching could become incorrect when tree-sitter
returned ambiguous bracket pairs for the same opening delimiter. The
repair path rebuilt pairs using a shared stack across all bracket query
patterns, which let excluded delimiters like Markdown single quotes
interfere with parenthesis matching.

This change scopes that repair logic to each bracket query pattern so
ambiguous matches are rebuilt without mixing unrelated delimiter types.
It also adds a regression test for the Markdown repro from the issue.

<img width="104" height="137" alt="image"
src="https://github.com/user-attachments/assets/4318bb4d-7072-4671-8fb5-c4478a179c07"
/>

<img width="104" height="137" alt="image"
src="https://github.com/user-attachments/assets/07a8a0fc-7618-4edb-a14e-645358d8d307"
/>


## How to Review

Review `crates/language/src/buffer.rs` first, especially the fallback
repair path for bogus tree-sitter bracket matches.

Then review `crates/editor/src/bracket_colorization.rs`, which adds
regression coverage for the issue repro.

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

- Fixed rainbow brackets in Markdown when quotes caused parentheses to
match incorrectly
2026-03-21 23:32:33 +00:00
2652089d46 editor: Fix rewrapping with an empty selection (#51742)
Closes #43043

Rewrapping logic for when there was nothing selected was desynced from
the code that handles selections.
The desired wrapping can be achieved when you selected the markdown
paragraph and use the rewrap action.

This PR moves the logic that selects lines for the case where there is
no selection further up to reuse the existing rewrapping logic

<img width="862" height="553" alt="image"
src="https://github.com/user-attachments/assets/87f7c6cb-7855-4193-b17a-f938f8c9a210"
/>

- [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 rewrapping paragraphs in markdown when you have nothing selected

---------

Co-authored-by: Tom Houlé <tom@tomhoule.com>
Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
2026-03-19 20:42:30 +01:00