- **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>
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
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.
## 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>
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-8ca097c0acb0https://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>
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
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
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
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>
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>
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>
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>
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>
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
## 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 ...
## 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
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)).
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>
* 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
## 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
## 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
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>
Closes#49957
Also adds `start_of_input` context, and modifies both
`{start,end}_of_input` to work for both single line and auto height
editor modes.
https://github.com/user-attachments/assets/e30f2b20-a96c-49d5-9eb6-3c95a485d14a
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:
- Added support for multi-line search and replace input in Buffer Search
and Project Search
---------
Co-authored-by: Nathan Sobo <nathan@zed.dev>
When typing with the macOS Accessibility Keyboard and clicking a word
completion suggestion, text was corrupted in several ways.
macOS sends `insertText:replacementRange:` when a completion is
selected. The replacement range was passed to
`selection_replacement_ranges` using the wrong offset type, causing
incorrect delta calculation for multi-cursor scenarios. Additionally,
`backspace` was called unconditionally even when the replacement range
was empty (as with the trailing space the Accessibility Keyboard
appends), deleting the last character of every completed word. Finally,
an empty replacement range in a multi-cursor context carries a stale
cursor position from macOS's single-cursor view of the buffer, so it is
now ignored and text is inserted at each cursor's actual position
instead.
Closes#38052
Release Notes:
- Fixed text corruption when using macOS Accessibility Keyboard word
completion.
Closes https://github.com/zed-industries/zed/issues/44203
Release Notes:
- Go to definition (and similar actions) will now no longer open a multi
buffer if there are multiple results that all fit into a single excerpt
Closes#5057
## Summary
The indent-based code fold detection does not account for lines inside
multiline strings or block comments that have less indentation than the
surrounding code. This causes the fold scanner to think the enclosing
block ends prematurely.
For example, folding `fn main()` here would fail because the raw string
content at indent level 0 gets treated as the end of the function body:
``` rust
fn main() {
let s = r#"
unindented content
"#;
}
```
This PR checks whether a low-indent line falls inside a string or
comment override region and skips it if so. This works across all
languages that define `@string` or `@comment` overrides in their
`overrides.scm`.
## Before
https://github.com/user-attachments/assets/a08e6bf8-4f25-4211-8a46-8f6da7e49247
## After
https://github.com/user-attachments/assets/cd5b36db-6d4d-420b-9d60-79f9fad8638e
## Test Plan
- Added `test_fold_with_unindented_multiline_raw_string`
- Added `test_fold_with_unindented_multiline_block_comment`
- All existing fold tests pass
- Manually tested both Rust and Python examples
Release Notes:
- Fixed code folding incorrectly collapsing when multiline strings or
block comments contained unindented content
When clicking on a sticky header line, the cursor is now placed at the
column corresponding to the click position, rather than always at the
start of the outline item's range. The hover cursor is also changed from
a pointing hand to an I-beam to reflect that clicking behaves like
clicking in normal editor text.
Release Notes:
- Clicking a sticky header now puts the cursor at the clicked column
Closes#48922
When the editor regains focus, it internally triggers the mouse_moved
logic again. This causes the hover documentation to be shown even if it
was previously dismissed due to user editing.
This change skips mouse_moved handling when the cursor is hidden,
preventing unintended tooltip popups.
[录屏 2026-02-11
19-04-14.webm](https://github.com/user-attachments/assets/ea9f9438-34bf-4771-bbc8-335e9ea59dd7)
- [x] Tests or screenshots needed?
- [x] Code Reviewed
- [x] Manual QA
Release Notes:
- Fixed documentation tooltip reappearing after editor regains focus
Closes#49662
## Summary
Fixes an index-out-of-bounds crash in `EditorElement::prepaint` that
occurs when block decorations oscillate in size, exhausting the
recursive prepaint budget (`MAX_PREPAINT_DEPTH = 5`).
## Root cause
When block decorations resize during `render_blocks`, prepaint recurses
to rebuild layout state. Previously, both `resize_blocks()` and
`update_renderer_widths()` mutated the display map **before** checking
`can_prepaint()`. At max depth:
1. `resize_blocks()` mutated the block map, changing the display row
mapping
2. `can_prepaint()` returned false, skipping the recursive rebuild
3. All local state (`snapshot`, `start_row`, `end_row`, `line_layouts`,
`row_infos`) remained stale
4. Downstream code — particularly `layout_inline_diagnostics` which
takes a **fresh** `editor.snapshot()` — would see the new row mapping
but index into the stale `line_layouts`
5. `row.minus(start_row)` produced an index exceeding
`line_layouts.len()` → panic
The crash is most likely to occur when many block decorations appear or
resize simultaneously (e.g., unfolding a folder containing many git
repos, causing a burst of diff hunk blocks), or when `place_near` blocks
oscillate between inline (height=0) and block (height>=1) mode, burning
through all 5 recursion levels without converging.
## Fix
Guard both mutation sites with `can_prepaint()` so the display map is
NOT mutated when we cannot recurse to rebuild state:
- **Block resize**: move `resize_blocks()` inside the `can_prepaint()`
guard. At max depth, defer the resize to the next frame via
`cx.notify()`. The resize will be re-detected because the stored height
still mismatches the rendered height.
https://github.com/jean-humann/zed/blob/021978ecf939723a6ba4ab9843572b6bcefe7cb7/crates/editor/src/element.rs#L10207-L10239
- **Renderer widths**: short-circuit `update_renderer_widths()` with
`can_prepaint()` so fold widths are not updated at max depth.
https://github.com/jean-humann/zed/blob/021978ecf939723a6ba4ab9843572b6bcefe7cb7/crates/editor/src/element.rs#L10097-L10115
In both cases the next frame starts with a fresh recursion budget
(`EditorRequestLayoutState::default()` resets `prepaint_depth` to 0) and
applies the deferred changes normally. The worst case is one frame of
slightly wrong-sized blocks — vastly preferable to a crash.
## Test plan
- [x] `cargo check -p editor` passes
- [ ] Manual testing with many open files, inline diagnostics, hover
popovers, and git diff hunks
Release Notes:
- Fixed a crash (index out of bounds) during editor rendering when block
decorations repeatedly resize, exhausting the recursive prepaint budget.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
- Simplify and improve Windows clipboard handler.
- Fixed components that weren't handling multiple formats on the
clipboard properly.
Closes https://github.com/zed-industries/zed/issues/51278
Release Notes:
- windows: Fixed an issue where text copied from Office applications
couldn't be pasted into Zed.
The tab context menu has "Copy Path", "Open in Terminal", and "Reveal In
Project Panel" but no way to reveal the file in the system file manager.
This action already exists in three other context menus (editor
right-click, project panel, outline panel) but was missing from tab
right-click.
## Changes
Adds a platform-specific entry to the tab context menu:
- **macOS:** "Reveal in Finder"
- **Windows:** "Reveal in File Explorer"
- **Linux:** "Reveal in File Manager"
Placed after "Copy Relative Path" and before "Pin Tab". Gated behind
`is_local` (including WSL with host interop) to match the project
panel's behavior. Uses the existing `project.reveal_path()`
infrastructure, which handles platform-specific file manager invocation
and WSL path conversion.
## Prior art
Every major editor has this in the tab context menu:
- VS Code: "Reveal in Finder" (macOS) / "Reveal in File Explorer"
(Windows)
- JetBrains IDEs: Right-click tab -> "Open in" -> "Finder"
- Sublime Text: Right-click tab -> "Reveal in Finder"
Zed already has this in the editor body right-click menu (`Cmd-K R`),
project panel (`Alt-Cmd-R`), and outline panel. The tab context menu was
the only place it was missing.
This contribution was developed with AI assistance (Claude Code).
Release Notes:
- Added "Reveal in Finder" to the tab context menu
## Screenshot

---------
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All of the important changes are in
[`db.rs`](https://github.com/zed-industries/zed/pull/51809/changes#diff-2f644eab943bfa58feec29256281a3d9e8d4d7784cd34783e845af8beb15b16d).
Consider reading the commit log in order to review this work.
The DB crate's macro and API was changed to fix flakiness observed in
the MultiWorkspace tests when run locally. This flakiness was caused by
a shared `static LazyLock`, that caused concurrent test runs to interact
with the same underlying in-memory database. This flakiness wasn't
possible on CI due to it's usage of `cargo nextest`, whose
process-per-test approach masked this problem.
Essentially, I've changed the `static_connection` macro to remove the
static database variable and redone the internal model. Now, all
database types are thin wrappers around a generic `AppDatabase`. The
`AppDatabase` collects all of the individual table's migrations via the
`inventory` crate, and so only runs the migrations once on startup,
rather than a dozen times on startup.
The new API requires a `cx` so that we can replace the database returned
at runtime, rather than relying exclusively on a process-global
thread-local. However, we are still using a `static LazyLock` so that we
only need to take an `&App`, instead of an `&mut App`. These databases
types are `Clone + Send + Sync`, so you can easily capture-and-move the
database into background tasks and other places that don't have a `cx`.
For tests that require database isolation, it is now possible to set
their own database in init. See
[`workspace::init_test`](https://github.com/zed-industries/zed/pull/51809/changes#diff-041673bbd1947a35d45945636c0055429dfc8b5985faf93f8a8a960c9ad31e28R13610),
for the flakiness fix.
Best part, this change should be entirely compiler driven, so the Zed
agent was able to make the app-wide refactor easily.
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
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Closes#17090
Hello! This is a feature that I really wanted, so I've created an
implementation of it. Hope u guys like it.
It was alto mentioned at [this
discussion](https://github.com/zed-industries/zed/discussions/30473)
The use cases were based on the [vscode
extension](https://marketplace.visualstudio.com/items?itemName=yo1dog.cursor-align)
(only spaces case was implemented)
- The algorithm is O(n + m × 2k), where:
- n = total cursors (for initial analysis, to understand how many
alignments will be performed)
- m = number of alignment columns
- k = number of alignment rows (first time to get the most-right
occurrence, the next one to create the `Vec` of edits)
Release Notes:
- Added `editor: align selections` command

<br>
Thank you for creating zed!
---------
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Closes#35947
## Summary
When a settings file was moved to a second pane and Zed restarted, the
file appeared in both panes. Closing it in one pane would close it in
the other.
## Root cause
`Editor::deserialize` restored standalone files (like settings.json) by
calling `workspace.open_abs_path()`, which routes through
`open_path_preview` → `pane.open_item()`, adding the editor to the
workspace's default pane. The caller (`SerializedPane::deserialize_to`)
then also adds the item to the target pane, so it ends up in two panes.
This also caused the SQL constraint violations @MrSubidubi noted: the
`items` table has `PRIMARY KEY(item_id, workspace_id)`, so the duplicate
triggers errors on the next serialisation cycle.
## Fix
Replace `workspace.open_abs_path()` with `project.open_local_buffer()`,
which opens the buffer without touching any pane. Pane placement is left
to `deserialize_to`.
https://github.com/user-attachments/assets/68d3c5b4-d002-429f-b907-ec21cb0019ec
## Test plan
- [x] Reproduced the original bug (settings file duplicated across panes
after restart)
- [x] Verified the fix: file restores only to the correct pane
- [x] Added regression test
(`test_deserialize_non_worktree_file_does_not_add_to_pane`)
- [x] Existing `items::tests::test_deserialize` passes (all 6 cases)
- [x] `cargo clippy -p editor` clean
Release Notes:
- Fixed settings file being restored to multiple panes after restart
([#35947](https://github.com/zed-industries/zed/issues/35947)).
When a file is deleted, the parent folder isn't colored which makes it
hard to know unless we look at the Git Panel.
This PR adds `Color::Deleted` to fix that.
<img width="366" height="428" alt="Screenshot 2026-03-14 at 7 56 04 PM"
src="https://github.com/user-attachments/assets/6ed3a3c7-e7e7-4b48-b89c-705a7c1ff634"
/>
Release Notes:
- Improved project panel to color folder with deleted file
Closes#48393
When switching the language of an unsaved buffer (e.g., from Plain Text
to JavaScript), the editor's edit_prediction_settings were not
recalculated. This caused the "This Buffer" toggle in the edit
prediction menu to show a stale state, making the first click a no-op. I
added a call to update_edit_prediction_settings in the LanguageChanged
event handler so the editor immediately reflects the correct edit
prediction state for the new language.
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 the "Show Edit Predictions For This Buffer" toggle being a no-op
in unsaved buffers after switching the buffer's language.
Closes discussion #34890
This is similar to the vim prev/next method/section motion, but more
flexible because this follows the items in editor's outline (Tree sitter
or LSP provided).
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:
- Added actions `editor::GoToPreviousSymbol` and
`editor::GoToNextSymbol` actions to go to the previous and next outline
symbol. This is either the tree sitter outline, or the LSP provided
outline depending on the configuration.
When accepting an autocomplete suggestion with multiple active cursors
using `CMD+D`, Zed applies the primary completion edit to all cursors.
However, the overlap check for LSP `additionalTextEdits` only verifies
the replace range of the newest cursor.
If user has a cursor inside an existing import statement at the top of
the file and another cursor further down, Zed fails to detect the
overlap at the top of the file. When the user auto-completes the import
statement ends up jumbled.
This fix updates the completion logic to calculate the commit ranges for
all active cursors and passes them to the LSP store. The overlap check
now iterates over all commit ranges to ensure auto-imports are correctly
discarded if they intersect with any of the user's multi-cursor edits.
Closes https://github.com/zed-industries/zed/issues/50314
### Before
https://github.com/user-attachments/assets/8d0f71ec-37ab-4714-a318-897d9ee5e56b
### After
https://github.com/user-attachments/assets/4c978167-3065-48c0-bc3c-547a2dd22ac3
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 an issue where accepting an autocomplete suggestion with
multiple cursors could result in duplicated or jumbled text in import
statements.
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 ...