Add severity argument to GoToDiagnostic actions (#33995)

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 commit is contained in:
Hilmar Wiegand 2025-07-15 16:03:57 +02:00 committed by GitHub
parent 858e176a1c
commit 050ed85d71
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 312 additions and 51 deletions

View file

@ -1,6 +1,7 @@
//! This module contains all actions supported by [`Editor`].
use super::*;
use gpui::{Action, actions};
use project::project_settings::GoToDiagnosticSeverityFilter;
use schemars::JsonSchema;
use util::serde::default_true;
@ -265,6 +266,24 @@ pub enum UuidVersion {
V7,
}
/// Goes to the next diagnostic in the file.
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
#[action(namespace = editor)]
#[serde(deny_unknown_fields)]
pub struct GoToDiagnostic {
#[serde(default)]
pub severity: GoToDiagnosticSeverityFilter,
}
/// Goes to the previous diagnostic in the file.
#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)]
#[action(namespace = editor)]
#[serde(deny_unknown_fields)]
pub struct GoToPreviousDiagnostic {
#[serde(default)]
pub severity: GoToDiagnosticSeverityFilter,
}
actions!(
debugger,
[
@ -424,8 +443,6 @@ actions!(
GoToDefinition,
/// Goes to definition in a split pane.
GoToDefinitionSplit,
/// Goes to the next diagnostic in the file.
GoToDiagnostic,
/// Goes to the next diff hunk.
GoToHunk,
/// Goes to the previous diff hunk.
@ -440,8 +457,6 @@ actions!(
GoToParentModule,
/// Goes to the previous change in the file.
GoToPreviousChange,
/// Goes to the previous diagnostic in the file.
GoToPreviousDiagnostic,
/// Goes to the type definition of the symbol at cursor.
GoToTypeDefinition,
/// Goes to type definition in a split pane.

View file

@ -134,7 +134,7 @@ use project::{
session::{Session, SessionEvent},
},
git_store::{GitStoreEvent, RepositoryEvent},
project_settings::DiagnosticSeverity,
project_settings::{DiagnosticSeverity, GoToDiagnosticSeverityFilter},
};
pub use git::blame::BlameRenderer;
@ -15086,7 +15086,7 @@ impl Editor {
pub fn go_to_diagnostic(
&mut self,
_: &GoToDiagnostic,
action: &GoToDiagnostic,
window: &mut Window,
cx: &mut Context<Self>,
) {
@ -15094,12 +15094,12 @@ impl Editor {
return;
}
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
self.go_to_diagnostic_impl(Direction::Next, window, cx)
self.go_to_diagnostic_impl(Direction::Next, action.severity, window, cx)
}
pub fn go_to_prev_diagnostic(
&mut self,
_: &GoToPreviousDiagnostic,
action: &GoToPreviousDiagnostic,
window: &mut Window,
cx: &mut Context<Self>,
) {
@ -15107,12 +15107,13 @@ impl Editor {
return;
}
self.hide_mouse_cursor(HideMouseCursorOrigin::MovementAction, cx);
self.go_to_diagnostic_impl(Direction::Prev, window, cx)
self.go_to_diagnostic_impl(Direction::Prev, action.severity, window, cx)
}
pub fn go_to_diagnostic_impl(
&mut self,
direction: Direction,
severity: GoToDiagnosticSeverityFilter,
window: &mut Window,
cx: &mut Context<Self>,
) {
@ -15128,9 +15129,11 @@ impl Editor {
fn filtered(
snapshot: EditorSnapshot,
severity: GoToDiagnosticSeverityFilter,
diagnostics: impl Iterator<Item = DiagnosticEntry<usize>>,
) -> impl Iterator<Item = DiagnosticEntry<usize>> {
diagnostics
.filter(move |entry| severity.matches(entry.diagnostic.severity))
.filter(|entry| entry.range.start != entry.range.end)
.filter(|entry| !entry.diagnostic.is_unnecessary)
.filter(move |entry| !snapshot.intersects_fold(entry.range.start))
@ -15139,12 +15142,14 @@ impl Editor {
let snapshot = self.snapshot(window, cx);
let before = filtered(
snapshot.clone(),
severity,
buffer
.diagnostics_in_range(0..selection.start)
.filter(|entry| entry.range.start <= selection.start),
);
let after = filtered(
snapshot,
severity,
buffer
.diagnostics_in_range(selection.start..buffer.len())
.filter(|entry| entry.range.start >= selection.start),

View file

@ -14734,7 +14734,7 @@ async fn go_to_prev_overlapping_diagnostic(executor: BackgroundExecutor, cx: &mu
executor.run_until_parked();
cx.update_editor(|editor, window, cx| {
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic, window, cx);
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic::default(), window, cx);
});
cx.assert_editor_state(indoc! {"
@ -14743,7 +14743,7 @@ async fn go_to_prev_overlapping_diagnostic(executor: BackgroundExecutor, cx: &mu
"});
cx.update_editor(|editor, window, cx| {
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic, window, cx);
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic::default(), window, cx);
});
cx.assert_editor_state(indoc! {"
@ -14752,7 +14752,7 @@ async fn go_to_prev_overlapping_diagnostic(executor: BackgroundExecutor, cx: &mu
"});
cx.update_editor(|editor, window, cx| {
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic, window, cx);
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic::default(), window, cx);
});
cx.assert_editor_state(indoc! {"
@ -14761,7 +14761,7 @@ async fn go_to_prev_overlapping_diagnostic(executor: BackgroundExecutor, cx: &mu
"});
cx.update_editor(|editor, window, cx| {
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic, window, cx);
editor.go_to_prev_diagnostic(&GoToPreviousDiagnostic::default(), window, cx);
});
cx.assert_editor_state(indoc! {"