Closes https://github.com/zed-industries/zed/issues/33980
Closes https://github.com/zed-industries/zed/discussions/33979
- Switches to the debounce task pattern for diagnostic summary
computations, which most importantly lets us do them only once when a
large number of DiagnosticUpdated events are received at once.
- Makes workspace diagnostic requests not time out if a partial result
is received.
- Makes diagnostics from workspace diagnostic partial results get
merged.
There might be some related areas where we're not fully complying with
the LSP spec but they may be outside the scope of what this PR should
include.
Release Notes:
- Added support for streaming LSP workspace diagnostics.
- Fixed editor freeze from large LSP workspace diagnostic responses.
This PR adds a `severity` argument so severity can be defined when
navigating through diagnostics. This allows keybinds like the following:
```json
{
"] e": ["editor::GoToDiagnostic", { "severity": "error" }],
"[ e": ["editor::GoToDiagnostic", { "severity": "error" }]
}
```
I've added test comments and a test. Let me know if there's anything
else you need!
Release Notes:
- Add `severity` argument to `editor::GoToDiagnostic`,
`editor::GoToPreviousDiagnostic`, `project_panel::SelectNextDiagnostic`
and `project_panel::SelectPrevDiagnostic` actions
This PR aims to improve the minimap performace. This is primarily
achieved by disabling/removing stuff that is not shown in the minimal as
well as by assuring the display map is not updated during minimap
prepaint.
This should already be much better in parts, as the block map as well as
the fold map will be less frequently updated due to the minimap
prepainting (optimally, they should never be, but I think we're not
quite there yet).
For this, I had to remove block rendering support for the minimap, which
is not as bad as it sounds: Practically, we were currently not rendering
most blocks anyway, there were issues due to this (e.g. scrolling any
visible block offscreen in the main editor causes scroll jumps
currently) and in the long run, the minimap will most likely need its
own block map or a different approach anyway. The existing
implementation caused resizes to occur very frequently for practically
no benefit. Can pull this out into a separate PR if requested, most
likely makes the other changes here easier to discuss.
This is WIP as we are still hitting some code path here we definitely
should not be hitting. E.g. there seems to be a rerender roughly every
second if the window is unfocused but visible which does not happen when
the minimap is disabled.
While this primarily focuses on the minimap, it also touches a few other
small parts not related to the minimap where I noticed we were doing too
much stuff during prepaint. Happy for any feedback there aswell.
Putting this up here already so we have a place to discuss the changes
early if needed.
Release Notes:
- Improved performance with the minimap enabled.
- Fixed an issue where interacting with blocks in the editor would
sometimes not properly work with the minimap enabled.
Closes #ISSUE
Adds a new `documentation` method to actions, that is extracted from doc
comments when using the `actions!` or derive macros.
Additionally, this PR adds doc comments to as many action definitions in
Zed as possible.
Release Notes:
- N/A *or* Added/Fixed/Improved ...
In #32656 I generalized the argument to change selections to allow
controling both the scroll and the nav history (and the completion
trigger).
To avoid conflicting with ongoing debugger cherry-picks I left the
argument as an `impl Into<>`, but I think it's clearer to make callers
specify what they want here.
I converted a lot of `None` arguments to `SelectionEffects::no_scroll()`
to be exactly compatible; but I think many people used none as an "i
don't care" value in which case Default::default() might be more
appropraite
Closes #ISSUE
Release Notes:
- N/A
In #32656 I generalized the argument to change selections to allow
controling both the scroll and the nav history (and the completion
trigger).
To avoid conflicting with ongoing debugger cherry-picks I left the
argument as an `impl Into<>`, but I think it's clearer to make callers
specify what they want here.
I converted a lot of `None` arguments to `SelectionEffects::no_scroll()`
to be exactly compatible; but I think many people used none as an "i
don't care" value in which case Default::default() might be more
appropraite
https://github.com/user-attachments/assets/ad0fa304-e4fb-4598-877d-c02141f35d6f
Closes https://github.com/zed-industries/zed/issues/4678
Also adds the code to support `textDocument/colorPresentation`
counterpart that serves as a resolve mechanism for the document colors.
The resolve itself is not run though, and the editor does not
accommodate color presentations in the editor yet — until a well
described use case is provided.
Use `lsp_document_colors` editor settings to alter the presentation and
turn the feature off.
Release Notes:
- Start showing inline previews for LSP document colors
Follow-up of https://github.com/zed-industries/zed/pull/19230
* starts to send `result_id` in pull requests to allow servers to reply
with non-full results
* fixes a bug where disk-based diagnostics were offset after pulling the
diagnostics
* fixes a bug due to which pull diagnostics could not be disabled
* uses better names and comments for the workspace pull diagnostics part
Release Notes:
- N/A
Closes [#13107](https://github.com/zed-industries/zed/issues/13107)
Enabled pull diagnostics by default, for the language servers that
declare support in the corresponding capabilities.
```
"diagnostics": {
"lsp_pull_diagnostics_debounce_ms": null
}
```
settings can be used to disable the pulling.
Release Notes:
- Added support for the LSP `textDocument/diagnostic` command.
# Brief
This is draft PR that implements the LSP `textDocument/diagnostic`
command. The goal is to receive your feedback and establish further
steps towards fully implementing this command. I tried to re-use
existing method and structures to ensure:
1. The existing functionality works as before
2. There is no interference between the diagnostics sent by a server and
the diagnostics requested by a client.
The current implementation is done via a new LSP command
`GetDocumentDiagnostics` that is sent when a buffer is saved and when a
buffer is edited. There is a new method called `pull_diagnostic` that is
called for such events. It has debounce to ensure we don't spam a server
with commands every time the buffer is edited. Probably, we don't need
the debounce when the buffer is saved.
All in all, the goal is basically to get your feedback and ensure I am
on the right track. Thanks!
## References
1.
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_pullDiagnostics
## In action
You can clone any Ruby repo since the `ruby-lsp` supports the pull
diagnostics only.
Steps to reproduce:
1. Clone this repo https://github.com/vitallium/stimulus-lsp-error-zed
2. Install Ruby (via `asdf` or `mise).
4. Install Ruby gems via `bundle install`
5. Install Ruby LSP with `gem install ruby-lsp`
6. Check out this PR and build Zed
7. Open any file and start editing to see diagnostics in realtime.
https://github.com/user-attachments/assets/0ef6ec41-e4fa-4539-8f2c-6be0d8be4129
---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
* project search button in the status bar
```jsonc
"search": {
"button": false
},
```
* project diagnostics button in the status bar
```jsonc
"diagnostics": {
"button": false
}
```
* project name and host buttons in the title bar
```jsonc
"title_bar": {
"show_project_items": false
}
```
* git branch button in the title bar
```jsonc
"title_bar": {
"show_branch_name": false
}
```
Before:
<img width="1728" alt="before"
src="https://github.com/user-attachments/assets/4b13b431-3ac1-43b3-8ac7-469e5a9ccf7e"
/>
After:
<img width="1728" alt="after"
src="https://github.com/user-attachments/assets/baf2765a-e27b-47a3-8897-89152b7a7c95"
/>
Release Notes:
- Added more settings to hide buttons from Zed UI
* Adds a `diagnostics_max_severity: null` editor settings that has
previous hardcoded default, `warning`
* Make inline diagnostics to inherit this setting by default (can be
overridden with its own max_severity setting)
* Allows to toggle diagnostics in the editor menu and via new action,
`editor::ToggleDiagnostics`
Closes https://github.com/zed-industries/zed/issues/4686
Release Notes:
- N/A *or* Added/Fixed/Improved ...
## Overview
This PR adds the minimap feature to the Zed editor, closely following
the [design from Visual Studio
Code](https://code.visualstudio.com/docs/getstarted/userinterface#_minimap).
When configured, a second instance of the editor will appear to the left
of the scrollbar. This instance is not interactive and it has a slimmed
down set of annotations, but it is otherwise just a zoomed-out version
of the main editor instance. A thumb shows the line boundaries of the
main viewport, as well as the progress through the document. Clicking on
a section of code in the minimap will jump the editor to that code.
Dragging the thumb will act like the scrollbar, moving sequentially
through the document.

## New settings
This adds a `minimap` section to the editor settings with the following
keys:
### `show`
When to show the minimap in the editor.
This setting can take three values:
1. Show the minimap if the editor's scrollbar is visible: `"auto"`
2. Always show the minimap: `"always"`
3. Never show the minimap: `"never"` (default)
### `thumb`
When to show the minimap thumb.
This setting can take two values:
1. Show the minimap thumb if the mouse is over the minimap: `"hover"`
2. Always show the minimap thumb: `"always"` (default)
### `width`
The width of the minimap in pixels.
Default: `100`
### `font_size`
The font size of the minimap in pixels.
Default: `2`
## Providing feedback
In order to keep the PR focused on development updates, please use the
discussion thread for feature suggestions and usability feedback: #26894
## Features left to add
- [x] fix scrolling performance
- [x] user settings for enable/disable, width, text size, etc.
- [x] show overview of visible lines in minimap
- [x] clicking on minimap should navigate to the corresponding section
of code
- ~[ ] more prominent highlighting in the minimap editor~
- ~[ ] override scrollbar auto setting to always when minimap is set to
always show~
Release Notes:
- Added minimap for high-level overview and quick navigation of editor
contents.
---------
Co-authored-by: MrSubidubi <dev@bahn.sh>
Co-authored-by: Kirill Bulatov <kirill@zed.dev>
Follow-up of https://github.com/zed-industries/zed/pull/29706
Instead of doing `cargo check` manually, use rust-analyzer's flycheck:
at the cost of more sophisticated check command configuration, we keep
much less code in Zed, and get a proper progress report.
User-facing UI does not change except `diagnostics_fetch_command` and
`env` settings removed from the diagnostics settings.
Release Notes:
- N/A
Adjusts the way `cargo` and `rust-analyzer` diagnostics are fetched into
Zed.
Nothing is changed for defaults: in this mode, Zed does nothing but
reports file updates, which trigger rust-analyzers'
mechanisms:
* generating internal diagnostics, which it is able to produce on the
fly, without blocking cargo lock.
Unfortunately, there are not that many diagnostics in r-a, and some of
them have false-positives compared to rustc ones
* running `cargo check --workspace --all-targets` on each file save,
taking the cargo lock
For large projects like Zed, this might take a while, reducing the
ability to choose how to work with the project: e.g. it's impossible to
save multiple times without long diagnostics refreshes (may happen
automatically on e.g. focus loss), save the project and run it instantly
without waiting for cargo check to finish, etc.
In addition, it's relatively tricky to reconfigure r-a to run a
different command, with different arguments and maybe different env
vars: that would require a language server restart (and a large project
reindex) and fiddling with multiple JSON fields.
The new mode aims to separate out cargo diagnostics into its own loop so
that all Zed diagnostics features are supported still.
For that, an extra mode was introduced:
```jsonc
"rust": {
// When enabled, Zed runs `cargo check --message-format=json`-based commands and
// collect cargo diagnostics instead of rust-analyzer.
"fetch_cargo_diagnostics": false,
// A command override for fetching the cargo diagnostics.
// First argument is the command, followed by the arguments.
"diagnostics_fetch_command": [
"cargo",
"check",
"--quiet",
"--workspace",
"--message-format=json",
"--all-targets",
"--keep-going"
],
// Extra environment variables to pass to the diagnostics fetch command.
"env": {}
}
```
which calls to cargo, parses its output and mixes in with the existing
diagnostics:
https://github.com/user-attachments/assets/e986f955-b452-4995-8aac-3049683dd22c
Release Notes:
- Added a way to get diagnostics from cargo and rust-analyzer without
mutually locking each other
- Added `ctrl-r` binding to refresh diagnostics in the project
diagnostics editor context
- Stop merging same row diagnostics
- (for Rust) show code fragments surrounded by `'s in monospace
Co-authored-by: Serge Radinovich <sergeradinovich@gmail.com>
Closes#29362
Release Notes:
- diagnostics: Diagnostics are no longer merged when they're on the same
line
- rust: Diagnostics now show code snippets in monospace font:
<img width="551" alt="Screenshot 2025-04-29 at 16 13 45"
src="https://github.com/user-attachments/assets/d289be31-717d-404f-a76a-a0cda3e96fbe"
/>
Co-authored-by: Serge Radinovich <sergeradinovich@gmail.com>
resolves#24655resolves#23945
I haven't yet added a default binding for the new command. #27797 added `:ls` and
`:buffers` which in my opinion should use the global searchable version
given that that matches the vim semantics of those commands better than
just showing the tabs in the local pane.
There's also a question of what to do when you select a tab from another
pane, should the focus jump to that pane or should that tab move to the
currently focused pane? For now I've implemented the former.
Release Notes:
- Added `tab_switcher::ToggleAll` to search open tabs from all panes and focus the selected one.
---------
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Closes#28135Closes#4388Closes#28136
Release Notes:
- diagnostics: Show the diagnostic code if available
---------
Co-authored-by: Neo Nie <nihgwu@live.com>
Co-authored-by: Zed AI <ai+claude-3.7@zed.dev>
Release Notes:
- "Block" diagnostics (that show up in the diagnostics view, or when
using `f8`/`shift-f8`) are rendered more clearly
- `f8`/`shift-f8` now always go to the "next" or "prev" diagnostic,
regardless of the state of the editor

---------
Co-authored-by: Kirill Bulatov <mail4score@gmail.com>
Co-authored-by: Julia Ryan <juliaryan3.14@gmail.com>
A "Near" block acts similarly to a "Below" block, but can (if it's
height is <= one line height) be shown on the end of the preceding line
instead of adding an entire blank line to the editor.
You can test it out by pasting this into `go_to_diagnostic_impl` and
then press `F8`
```
let buffer = self.buffer.read(cx).snapshot(cx);
let selection = self.selections.newest_anchor();
self.display_map.update(cx, |display_map, cx| {
display_map.insert_blocks(
[BlockProperties {
placement: BlockPlacement::Near(selection.start),
height: Some(1),
style: BlockStyle::Flex,
render: Arc::new(|_| {
div()
.w(px(100.))
.h(px(16.))
.bg(gpui::hsla(0., 0., 1., 0.5))
.into_any_element()
}),
priority: 0,
}],
cx,
)
});
return;
```
Release Notes:
- N/A
---------
Co-authored-by: Antonio Scandurra <me@as-cii.com>
This adds a "workspace-hack" crate, see
[mozilla's](https://hg.mozilla.org/mozilla-central/file/3a265fdc9f33e5946f0ca0a04af73acd7e6d1a39/build/workspace-hack/Cargo.toml#l7)
for a concise explanation of why this is useful. For us in practice this
means that if I were to run all the tests (`cargo nextest r
--workspace`) and then `cargo r`, all the deps from the previous cargo
command will be reused. Before this PR it would rebuild many deps due to
resolving different sets of features for them. For me this frequently
caused long rebuilds when things "should" already be cached.
To avoid manually maintaining our workspace-hack crate, we will use
[cargo hakari](https://docs.rs/cargo-hakari) to update the build files
when there's a necessary change. I've added a step to CI that checks
whether the workspace-hack crate is up to date, and instructs you to
re-run `script/update-workspace-hack` when it fails.
Finally, to make sure that people can still depend on crates in our
workspace without pulling in all the workspace deps, we use a `[patch]`
section following [hakari's
instructions](https://docs.rs/cargo-hakari/0.9.36/cargo_hakari/patch_directive/index.html)
One possible followup task would be making guppy use our
`rust-toolchain.toml` instead of having to duplicate that list in its
config, I opened an issue for that upstream: guppy-rs/guppy#481.
TODO:
- [x] Fix the extension test failure
- [x] Ensure the dev dependencies aren't being unified by Hakari into
the main dependencies
- [x] Ensure that the remote-server binary continues to not depend on
LibSSL
Release Notes:
- N/A
---------
Co-authored-by: Mikayla <mikayla@zed.dev>
Co-authored-by: Mikayla Maki <mikayla.c.maki@gmail.com>
This is the core change:
https://github.com/zed-industries/zed/pull/26758/files#diff-044302c0d57147af17e68a0009fee3e8dcdfb4f32c27a915e70cfa80e987f765R1052
TODO:
- [x] Use AsyncFn instead of Fn() -> Future in GPUI spawn methods
- [x] Implement it in the whole app
- [x] Implement it in the debugger
- [x] Glance at the RPC crate, and see if those box future methods can
be switched over. Answer: It can't directly, as you can't make an
AsyncFn* into a trait object. There's ways around that, but they're all
more complex than just keeping the code as is.
- [ ] Fix platform specific code
Release Notes:
- N/A
Release Notes:
- Multibuffers now use less vertical space for excerpt boundaries.
Additionally the expand up/down arrows are hidden at the start and end
of the buffers
---------
Co-authored-by: Nate Butler <iamnbutler@gmail.com>
Co-authored-by: Zed AI <claude-3.5-sonnet@zed.dev>
Closes#25509
Changes:
- If active item is already diagnostics, don't try to focus it again.
Instead of not focusing, should it just not activate instead? Something
like:
if !workspace
.active_item(cx)
.map(|item| item.item_id() == existing.item_id())
.unwrap_or(false)
{
workspace.activate_item(&existing, true, true, window, cx);
}
Release Notes:
- N/A
This PR adds toasts for reporting success and errors from remote git
operations. This PR also adds a focus handle to notifications, in
anticipation of making them keyboard accessible.
Release Notes:
- N/A
---------
Co-authored-by: julia <julia@zed.dev>
When migrating to gpui2,
588976d27a (diff-a3da3181e4ab4f73aa1697d7b6dc0caa0c17b2a187fb83b076dfc0234ec91f54R21)
removed the diagnostic style for "active but invalid" case: presumably,
it served as some sort of a cursor to show where to move on after the
diagnostics update, on the next `GoTo[Prev]Diagnostic` action call.
As this change went unchanged for some time, another approach is tested
now, to be more integrated with inline diagnostics: now, the active
state is cleared
Same as before this change, another `GoTo[Prev]Diagnostic` action call
will be needed to re-expand a new diagnostics, but this change makes
this expansion to happen after the cursor — before the change, Zed would
continue from the stale diagnostics.
Release Notes:
- Fixed active diagnostics becoming stale
Related to #18300
Release Notes:
- Improved diagnostic pane responsiveness with large # of diagnostics.
---------
Co-authored-by: Anthony Eid <hello@anthonyeid.me>
- **store `buffer::Diagnostic`as NumberOrString instead of assuming
String**
- **update zed-industries/lsp-types rev**
Closes#24081
Release Notes:
- Fixed an issue where language server diagnostic codes would be converted to strings leading to errors with some language servers
This PR builds on #21258 to make it possible to use HEAD as a diff base.
The buffer store is extended to support holding multiple change sets,
and collab gains support for synchronizing the committed text of files
when any collaborator requires it.
Not implemented in this PR:
- Exposing the diff from HEAD to the user
- Decorating the diff from HEAD with information about which hunks are
staged
`test_random_multibuffer` now fails first at `SEED=13277`, similar to
the previous high-water mark, but with various bugs in the multibuffer
logic now shaken out.
Release Notes:
- N/A
---------
Co-authored-by: Max <max@zed.dev>
Co-authored-by: Ben <ben@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Conrad <conrad@zed.dev>
I believe this takes care of the remaining events running through the
old flow that requires transformation at the collab server level. I
think all events are now going through `telemetry::event!()`.
For anyone curious where the new telemetry names are coming from, you
can check the `for_snowflake` function within
`crates/collab/src/api/events.rs`, to see how collab is currently
transforming the events going through the old flow.
Release Notes:
- N/A
In the left hand status bar, there are two groups of buttons. There was
a border between the two hardcoded on the first button of the second
group, however, if all buttons in the first group are hidden, the border
doesn't need to be rendered.
(Not handled in this PR) A potentially better approach would be to
change StatusBar's definition from `left_items` and `right_items` to
`left_groups` and `right_groups`, and render dividers between each group
of items. That seemed like a bigger refactor than I wanted to handle for
now, but is an option for the future.
If you use these settings on `main`, the border will show, but with
nothing to the left of it.
```json
{
"collaboration_panel": {
"button": false
},
"outline_panel": {
"button": false
},
"project_panel": {
"button": false,
},
}
```
Screenshots:
Before:
<img width="117" alt="Screenshot 2025-02-02 at 6 19 24 PM"
src="https://github.com/user-attachments/assets/b3401b47-6172-4392-9277-31aa1affaf7a"
/>
<img width="134" alt="Screenshot 2025-02-02 at 6 20 12 PM"
src="https://github.com/user-attachments/assets/1e8caee6-1da8-47f6-8499-9a93b6d8fa27"
/>
After:
<img width="125" alt="Screenshot 2025-02-02 at 6 19 58 PM"
src="https://github.com/user-attachments/assets/9b9f421c-660b-41cb-80e0-acb774c66054"
/>
<img width="132" alt="Screenshot 2025-02-02 at 6 20 20 PM"
src="https://github.com/user-attachments/assets/87e0e475-084b-44df-b820-573c68728c1a"
/>
Release Notes:
- Conditionally render divider in status bar
---------
Co-authored-by: Danilo Leal <67129314+danilo-leal@users.noreply.github.com>