@@ -10653,6 +10653,176 @@ async fn go_to_prev_overlapping_diagnostic(
"});
}
+#[gpui::test]
+async fn cycle_through_same_place_diagnostics(
+ executor: BackgroundExecutor,
+ cx: &mut gpui::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! {"
+ ˇfn func(abc def: i32) -> u32 {
+ }
+ "});
+
+ 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, 11),
+ lsp::Position::new(0, 12),
+ ),
+ severity: Some(lsp::DiagnosticSeverity::ERROR),
+ ..Default::default()
+ },
+ lsp::Diagnostic {
+ range: lsp::Range::new(
+ lsp::Position::new(0, 12),
+ lsp::Position::new(0, 15),
+ ),
+ severity: Some(lsp::DiagnosticSeverity::ERROR),
+ ..Default::default()
+ },
+ lsp::Diagnostic {
+ range: lsp::Range::new(
+ lsp::Position::new(0, 12),
+ lsp::Position::new(0, 15),
+ ),
+ severity: Some(lsp::DiagnosticSeverity::ERROR),
+ ..Default::default()
+ },
+ lsp::Diagnostic {
+ range: lsp::Range::new(
+ lsp::Position::new(0, 25),
+ lsp::Position::new(0, 28),
+ ),
+ severity: Some(lsp::DiagnosticSeverity::ERROR),
+ ..Default::default()
+ },
+ ],
+ },
+ &[],
+ cx,
+ )
+ .unwrap()
+ });
+ });
+ executor.run_until_parked();
+
+ //// Backward
+
+ // Fourth diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_prev_diagnostic(&GoToPrevDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc def: i32) -> ˇu32 {
+ }
+ "});
+
+ // Third diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_prev_diagnostic(&GoToPrevDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc ˇdef: i32) -> u32 {
+ }
+ "});
+
+ // Second diagnostic, same place
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_prev_diagnostic(&GoToPrevDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc ˇdef: i32) -> u32 {
+ }
+ "});
+
+ // First diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_prev_diagnostic(&GoToPrevDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abcˇ def: i32) -> u32 {
+ }
+ "});
+
+ // Wrapped over, fourth diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_prev_diagnostic(&GoToPrevDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc def: i32) -> ˇu32 {
+ }
+ "});
+
+ cx.update_editor(|editor, window, cx| {
+ editor.move_to_beginning(&MoveToBeginning, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ ˇfn func(abc def: i32) -> u32 {
+ }
+ "});
+
+ //// Forward
+
+ // First diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_diagnostic(&GoToDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abcˇ def: i32) -> u32 {
+ }
+ "});
+
+ // Second diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_diagnostic(&GoToDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc ˇdef: i32) -> u32 {
+ }
+ "});
+
+ // Third diagnostic, same place
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_diagnostic(&GoToDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc ˇdef: i32) -> u32 {
+ }
+ "});
+
+ // Fourth diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_diagnostic(&GoToDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abc def: i32) -> ˇu32 {
+ }
+ "});
+
+ // Wrapped around, first diagnostic
+ cx.update_editor(|editor, window, cx| {
+ editor.go_to_diagnostic(&GoToDiagnostic, window, cx);
+ });
+ cx.assert_editor_state(indoc! {"
+ fn func(abcˇ def: i32) -> u32 {
+ }
+ "});
+}
+
#[gpui::test]
async fn test_diagnostics_with_links(cx: &mut TestAppContext) {
init_test(cx, |_| {});