diff --git a/assets/keymaps/default-linux.json b/assets/keymaps/default-linux.json index 2a4b8acd44..02d08347fe 100644 --- a/assets/keymaps/default-linux.json +++ b/assets/keymaps/default-linux.json @@ -475,8 +475,8 @@ "ctrl-/": ["editor::ToggleComments", { "advance_downwards": false }], "ctrl-u": "editor::UndoSelection", "ctrl-shift-u": "editor::RedoSelection", - "f8": "editor::GoToDiagnostic", - "shift-f8": "editor::GoToPreviousDiagnostic", + "f8": ["editor::GoToDiagnostic", { "severity": { "min": "hint", "max": "error" } }], + "shift-f8": ["editor::GoToPreviousDiagnostic", { "severity": { "min": "hint", "max": "error" } }], "f2": "editor::Rename", "f12": "editor::GoToDefinition", "alt-f12": "editor::GoToDefinitionSplit", diff --git a/assets/keymaps/default-macos.json b/assets/keymaps/default-macos.json index 85766ecc3e..ecb8648978 100644 --- a/assets/keymaps/default-macos.json +++ b/assets/keymaps/default-macos.json @@ -528,8 +528,8 @@ "cmd-/": ["editor::ToggleComments", { "advance_downwards": false }], "cmd-u": "editor::UndoSelection", "cmd-shift-u": "editor::RedoSelection", - "f8": "editor::GoToDiagnostic", - "shift-f8": "editor::GoToPreviousDiagnostic", + "f8": ["editor::GoToDiagnostic", { "severity": { "min": "hint", "max": "error" } }], + "shift-f8": ["editor::GoToPreviousDiagnostic", { "severity": { "min": "hint", "max": "error" } }], "f2": "editor::Rename", "f12": "editor::GoToDefinition", "alt-f12": "editor::GoToDefinitionSplit", diff --git a/crates/diagnostics/src/diagnostics_tests.rs b/crates/diagnostics/src/diagnostics_tests.rs index 0d47eaf367..1364aaf853 100644 --- a/crates/diagnostics/src/diagnostics_tests.rs +++ b/crates/diagnostics/src/diagnostics_tests.rs @@ -14,7 +14,10 @@ use indoc::indoc; use language::{DiagnosticSourceKind, Rope}; use lsp::LanguageServerId; use pretty_assertions::assert_eq; -use project::FakeFs; +use project::{ + FakeFs, + project_settings::{GoToDiagnosticSeverity, GoToDiagnosticSeverityFilter}, +}; use rand::{Rng, rngs::StdRng, seq::IteratorRandom as _}; use serde_json::json; use settings::SettingsStore; @@ -1005,7 +1008,7 @@ async fn active_diagnostics_dismiss_after_invalidation(cx: &mut TestAppContext) cx.run_until_parked(); cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); assert_eq!( editor .active_diagnostic_group() @@ -1047,7 +1050,7 @@ async fn active_diagnostics_dismiss_after_invalidation(cx: &mut TestAppContext) "}); cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); assert_eq!(editor.active_diagnostic_group(), None); }); cx.assert_editor_state(indoc! {" @@ -1126,7 +1129,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Fourth diagnostic 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! {" fn func(abc def: i32) -> ˇu32 { @@ -1135,7 +1138,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Third diagnostic 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! {" fn func(abc ˇdef: i32) -> u32 { @@ -1144,7 +1147,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Second diagnostic, same place 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! {" fn func(abc ˇdef: i32) -> u32 { @@ -1153,7 +1156,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // First diagnostic 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! {" fn func(abcˇ def: i32) -> u32 { @@ -1162,7 +1165,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Wrapped over, fourth diagnostic 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! {" fn func(abc def: i32) -> ˇu32 { @@ -1181,7 +1184,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // First diagnostic cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); }); cx.assert_editor_state(indoc! {" fn func(abcˇ def: i32) -> u32 { @@ -1190,7 +1193,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Second diagnostic cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); }); cx.assert_editor_state(indoc! {" fn func(abc ˇdef: i32) -> u32 { @@ -1199,7 +1202,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Third diagnostic, same place cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); }); cx.assert_editor_state(indoc! {" fn func(abc ˇdef: i32) -> u32 { @@ -1208,7 +1211,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Fourth diagnostic cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); }); cx.assert_editor_state(indoc! {" fn func(abc def: i32) -> ˇu32 { @@ -1217,7 +1220,7 @@ async fn cycle_through_same_place_diagnostics(cx: &mut TestAppContext) { // Wrapped around, first diagnostic cx.update_editor(|editor, window, cx| { - editor.go_to_diagnostic(&GoToDiagnostic, window, cx); + editor.go_to_diagnostic(&GoToDiagnostic::default(), window, cx); }); cx.assert_editor_state(indoc! {" fn func(abcˇ def: i32) -> u32 { @@ -1441,6 +1444,128 @@ async fn test_diagnostics_with_code(cx: &mut TestAppContext) { ); } +#[gpui::test] +async fn go_to_diagnostic_with_severity(cx: &mut TestAppContext) { + init_test(cx); + + let mut cx = EditorTestContext::new(cx).await; + let lsp_store = + cx.update_editor(|editor, _, cx| editor.project.as_ref().unwrap().read(cx).lsp_store()); + + cx.set_state(indoc! {"error warning info hiˇnt"}); + + cx.update(|_, cx| { + lsp_store.update(cx, |lsp_store, cx| { + lsp_store + .update_diagnostics( + LanguageServerId(0), + lsp::PublishDiagnosticsParams { + uri: lsp::Url::from_file_path(path!("/root/file")).unwrap(), + version: None, + diagnostics: vec![ + lsp::Diagnostic { + range: lsp::Range::new( + lsp::Position::new(0, 0), + lsp::Position::new(0, 5), + ), + severity: Some(lsp::DiagnosticSeverity::ERROR), + ..Default::default() + }, + lsp::Diagnostic { + range: lsp::Range::new( + lsp::Position::new(0, 6), + lsp::Position::new(0, 13), + ), + severity: Some(lsp::DiagnosticSeverity::WARNING), + ..Default::default() + }, + lsp::Diagnostic { + range: lsp::Range::new( + lsp::Position::new(0, 14), + lsp::Position::new(0, 18), + ), + severity: Some(lsp::DiagnosticSeverity::INFORMATION), + ..Default::default() + }, + lsp::Diagnostic { + range: lsp::Range::new( + lsp::Position::new(0, 19), + lsp::Position::new(0, 23), + ), + severity: Some(lsp::DiagnosticSeverity::HINT), + ..Default::default() + }, + ], + }, + None, + DiagnosticSourceKind::Pushed, + &[], + cx, + ) + .unwrap() + }); + }); + cx.run_until_parked(); + + macro_rules! go { + ($severity:expr) => { + cx.update_editor(|editor, window, cx| { + editor.go_to_diagnostic( + &GoToDiagnostic { + severity: $severity, + }, + window, + cx, + ); + }); + }; + } + + // Default, should cycle through all diagnostics + go!(GoToDiagnosticSeverityFilter::default()); + cx.assert_editor_state(indoc! {"ˇerror warning info hint"}); + go!(GoToDiagnosticSeverityFilter::default()); + cx.assert_editor_state(indoc! {"error ˇwarning info hint"}); + go!(GoToDiagnosticSeverityFilter::default()); + cx.assert_editor_state(indoc! {"error warning ˇinfo hint"}); + go!(GoToDiagnosticSeverityFilter::default()); + cx.assert_editor_state(indoc! {"error warning info ˇhint"}); + go!(GoToDiagnosticSeverityFilter::default()); + cx.assert_editor_state(indoc! {"ˇerror warning info hint"}); + + let only_info = GoToDiagnosticSeverityFilter::Only(GoToDiagnosticSeverity::Information); + go!(only_info); + cx.assert_editor_state(indoc! {"error warning ˇinfo hint"}); + go!(only_info); + cx.assert_editor_state(indoc! {"error warning ˇinfo hint"}); + + let no_hints = GoToDiagnosticSeverityFilter::Range { + min: GoToDiagnosticSeverity::Information, + max: GoToDiagnosticSeverity::Error, + }; + + go!(no_hints); + cx.assert_editor_state(indoc! {"ˇerror warning info hint"}); + go!(no_hints); + cx.assert_editor_state(indoc! {"error ˇwarning info hint"}); + go!(no_hints); + cx.assert_editor_state(indoc! {"error warning ˇinfo hint"}); + go!(no_hints); + cx.assert_editor_state(indoc! {"ˇerror warning info hint"}); + + let warning_info = GoToDiagnosticSeverityFilter::Range { + min: GoToDiagnosticSeverity::Information, + max: GoToDiagnosticSeverity::Warning, + }; + + go!(warning_info); + cx.assert_editor_state(indoc! {"error ˇwarning info hint"}); + go!(warning_info); + cx.assert_editor_state(indoc! {"error warning ˇinfo hint"}); + go!(warning_info); + cx.assert_editor_state(indoc! {"error ˇwarning info hint"}); +} + fn init_test(cx: &mut TestAppContext) { cx.update(|cx| { zlog::init_test(); diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index b5f9e901bb..4eea5e7e1f 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -6,7 +6,7 @@ use gpui::{ WeakEntity, Window, }; use language::Diagnostic; -use project::project_settings::ProjectSettings; +use project::project_settings::{GoToDiagnosticSeverityFilter, ProjectSettings}; use settings::Settings; use ui::{Button, ButtonLike, Color, Icon, IconName, Label, Tooltip, h_flex, prelude::*}; use workspace::{StatusItemView, ToolbarItemEvent, Workspace, item::ItemHandle}; @@ -77,7 +77,7 @@ impl Render for DiagnosticIndicator { .tooltip(|window, cx| { Tooltip::for_action( "Next Diagnostic", - &editor::actions::GoToDiagnostic, + &editor::actions::GoToDiagnostic::default(), window, cx, ) @@ -156,7 +156,12 @@ impl DiagnosticIndicator { fn go_to_next_diagnostic(&mut self, window: &mut Window, cx: &mut Context) { if let Some(editor) = self.active_editor.as_ref().and_then(|e| e.upgrade()) { editor.update(cx, |editor, cx| { - editor.go_to_diagnostic_impl(editor::Direction::Next, window, cx); + editor.go_to_diagnostic_impl( + editor::Direction::Next, + GoToDiagnosticSeverityFilter::default(), + window, + cx, + ); }) } } diff --git a/crates/editor/src/actions.rs b/crates/editor/src/actions.rs index e12bdf7a07..c4866179c1 100644 --- a/crates/editor/src/actions.rs +++ b/crates/editor/src/actions.rs @@ -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. diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 919d7cc9c7..72470c0a7d 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -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, ) { @@ -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, ) { @@ -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, ) { @@ -15128,9 +15129,11 @@ impl Editor { fn filtered( snapshot: EditorSnapshot, + severity: GoToDiagnosticSeverityFilter, diagnostics: impl Iterator>, ) -> impl Iterator> { 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), diff --git a/crates/editor/src/editor_tests.rs b/crates/editor/src/editor_tests.rs index 6e0b949cb7..43c9c0db65 100644 --- a/crates/editor/src/editor_tests.rs +++ b/crates/editor/src/editor_tests.rs @@ -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! {" diff --git a/crates/project/src/project_settings.rs b/crates/project/src/project_settings.rs index 1c35f16522..a85d90fe33 100644 --- a/crates/project/src/project_settings.rs +++ b/crates/project/src/project_settings.rs @@ -326,6 +326,79 @@ impl DiagnosticSeverity { } } +/// Determines the severity of the diagnostic that should be moved to. +#[derive(PartialEq, PartialOrd, Clone, Copy, Debug, Eq, Deserialize, JsonSchema)] +#[serde(rename_all = "snake_case")] +pub enum GoToDiagnosticSeverity { + /// Errors + Error = 3, + /// Warnings + Warning = 2, + /// Information + Information = 1, + /// Hints + Hint = 0, +} + +impl From for GoToDiagnosticSeverity { + fn from(severity: lsp::DiagnosticSeverity) -> Self { + match severity { + lsp::DiagnosticSeverity::ERROR => Self::Error, + lsp::DiagnosticSeverity::WARNING => Self::Warning, + lsp::DiagnosticSeverity::INFORMATION => Self::Information, + lsp::DiagnosticSeverity::HINT => Self::Hint, + _ => Self::Error, + } + } +} + +impl GoToDiagnosticSeverity { + pub fn min() -> Self { + Self::Hint + } + + pub fn max() -> Self { + Self::Error + } +} + +/// Allows filtering diagnostics that should be moved to. +#[derive(PartialEq, Clone, Copy, Debug, Deserialize, JsonSchema)] +#[serde(untagged)] +pub enum GoToDiagnosticSeverityFilter { + /// Move to diagnostics of a specific severity. + Only(GoToDiagnosticSeverity), + + /// Specify a range of severities to include. + Range { + /// Minimum severity to move to. Defaults no "error". + #[serde(default = "GoToDiagnosticSeverity::min")] + min: GoToDiagnosticSeverity, + /// Maximum severity to move to. Defaults to "hint". + #[serde(default = "GoToDiagnosticSeverity::max")] + max: GoToDiagnosticSeverity, + }, +} + +impl Default for GoToDiagnosticSeverityFilter { + fn default() -> Self { + Self::Range { + min: GoToDiagnosticSeverity::min(), + max: GoToDiagnosticSeverity::max(), + } + } +} + +impl GoToDiagnosticSeverityFilter { + pub fn matches(&self, severity: lsp::DiagnosticSeverity) -> bool { + let severity: GoToDiagnosticSeverity = severity.into(); + match self { + Self::Only(target) => *target == severity, + Self::Range { min, max } => severity >= *min && severity <= *max, + } + } +} + #[derive(Copy, Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] pub struct GitSettings { /// Whether or not to show the git gutter. diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index 9f799b5be6..8f4aa12354 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -33,6 +33,7 @@ use project::{ Entry, EntryKind, Fs, GitEntry, GitEntryRef, GitTraversal, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId, git_store::{GitStoreEvent, git_traversal::ChildEntriesGitIter}, + project_settings::GoToDiagnosticSeverityFilter, relativize_path, }; use project_panel_settings::{ @@ -206,6 +207,24 @@ struct Trash { pub skip_prompt: bool, } +/// Selects the next entry with diagnostics. +#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)] +#[action(namespace = project_panel)] +#[serde(deny_unknown_fields)] +struct SelectNextDiagnostic { + #[serde(default)] + pub severity: GoToDiagnosticSeverityFilter, +} + +/// Selects the previous entry with diagnostics. +#[derive(PartialEq, Clone, Default, Debug, Deserialize, JsonSchema, Action)] +#[action(namespace = project_panel)] +#[serde(deny_unknown_fields)] +struct SelectPrevDiagnostic { + #[serde(default)] + pub severity: GoToDiagnosticSeverityFilter, +} + actions!( project_panel, [ @@ -255,10 +274,6 @@ actions!( SelectNextGitEntry, /// Selects the previous entry with git changes. SelectPrevGitEntry, - /// Selects the next entry with diagnostics. - SelectNextDiagnostic, - /// Selects the previous entry with diagnostics. - SelectPrevDiagnostic, /// Selects the next directory. SelectNextDirectory, /// Selects the previous directory. @@ -1954,7 +1969,7 @@ impl ProjectPanel { fn select_prev_diagnostic( &mut self, - _: &SelectPrevDiagnostic, + action: &SelectPrevDiagnostic, _: &mut Window, cx: &mut Context, ) { @@ -1973,7 +1988,8 @@ impl ProjectPanel { && entry.is_file() && self .diagnostics - .contains_key(&(worktree_id, entry.path.to_path_buf())) + .get(&(worktree_id, entry.path.to_path_buf())) + .is_some_and(|severity| action.severity.matches(*severity)) }, cx, ); @@ -1989,7 +2005,7 @@ impl ProjectPanel { fn select_next_diagnostic( &mut self, - _: &SelectNextDiagnostic, + action: &SelectNextDiagnostic, _: &mut Window, cx: &mut Context, ) { @@ -2008,7 +2024,8 @@ impl ProjectPanel { && entry.is_file() && self .diagnostics - .contains_key(&(worktree_id, entry.path.to_path_buf())) + .get(&(worktree_id, entry.path.to_path_buf())) + .is_some_and(|severity| action.severity.matches(*severity)) }, cx, ); diff --git a/crates/vim/src/command.rs b/crates/vim/src/command.rs index c001f55a41..74aed815a2 100644 --- a/crates/vim/src/command.rs +++ b/crates/vim/src/command.rs @@ -1106,13 +1106,28 @@ fn generate_commands(_: &App) -> Vec { VimCommand::str(("cl", "ist"), "diagnostics::Deploy"), VimCommand::new(("cc", ""), editor::actions::Hover), VimCommand::new(("ll", ""), editor::actions::Hover), - VimCommand::new(("cn", "ext"), editor::actions::GoToDiagnostic).range(wrap_count), - VimCommand::new(("cp", "revious"), editor::actions::GoToPreviousDiagnostic) + VimCommand::new(("cn", "ext"), editor::actions::GoToDiagnostic::default()) .range(wrap_count), - VimCommand::new(("cN", "ext"), editor::actions::GoToPreviousDiagnostic).range(wrap_count), - VimCommand::new(("lp", "revious"), editor::actions::GoToPreviousDiagnostic) - .range(wrap_count), - VimCommand::new(("lN", "ext"), editor::actions::GoToPreviousDiagnostic).range(wrap_count), + VimCommand::new( + ("cp", "revious"), + editor::actions::GoToPreviousDiagnostic::default(), + ) + .range(wrap_count), + VimCommand::new( + ("cN", "ext"), + editor::actions::GoToPreviousDiagnostic::default(), + ) + .range(wrap_count), + VimCommand::new( + ("lp", "revious"), + editor::actions::GoToPreviousDiagnostic::default(), + ) + .range(wrap_count), + VimCommand::new( + ("lN", "ext"), + editor::actions::GoToPreviousDiagnostic::default(), + ) + .range(wrap_count), VimCommand::new(("j", "oin"), JoinLines).range(select_range), VimCommand::new(("fo", "ld"), editor::actions::FoldSelectedRanges).range(act_on_range), VimCommand::new(("foldo", "pen"), editor::actions::UnfoldLines) diff --git a/crates/zed/src/zed/app_menus.rs b/crates/zed/src/zed/app_menus.rs index dac9f6495b..ddab724f4a 100644 --- a/crates/zed/src/zed/app_menus.rs +++ b/crates/zed/src/zed/app_menus.rs @@ -199,8 +199,11 @@ pub fn app_menus() -> Vec { MenuItem::action("Go to Type Definition", editor::actions::GoToTypeDefinition), MenuItem::action("Find All References", editor::actions::FindAllReferences), MenuItem::separator(), - MenuItem::action("Next Problem", editor::actions::GoToDiagnostic), - MenuItem::action("Previous Problem", editor::actions::GoToPreviousDiagnostic), + MenuItem::action("Next Problem", editor::actions::GoToDiagnostic::default()), + MenuItem::action( + "Previous Problem", + editor::actions::GoToPreviousDiagnostic::default(), + ), ], }, Menu { diff --git a/crates/zed/src/zed/quick_action_bar.rs b/crates/zed/src/zed/quick_action_bar.rs index 36d446579a..c95d86c84f 100644 --- a/crates/zed/src/zed/quick_action_bar.rs +++ b/crates/zed/src/zed/quick_action_bar.rs @@ -255,8 +255,11 @@ impl Render for QuickActionBar { .action("Go to Symbol", Box::new(ToggleOutline)) .action("Go to Line/Column", Box::new(ToggleGoToLine)) .separator() - .action("Next Problem", Box::new(GoToDiagnostic)) - .action("Previous Problem", Box::new(GoToPreviousDiagnostic)) + .action("Next Problem", Box::new(GoToDiagnostic::default())) + .action( + "Previous Problem", + Box::new(GoToPreviousDiagnostic::default()), + ) .separator() .action_disabled_when(!has_diff_hunks, "Next Hunk", Box::new(GoToHunk)) .action_disabled_when(