[WIP] editor: Implement next/prev reference (#41078)

Co-authored-by: Cole <cole@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
This commit is contained in:
Cameron Mcloughlin
2025-10-28 20:41:44 +00:00
committed by GitHub
co-authored by Cole Conrad Irwin
parent b75736568b
commit 5e7927f628
7 changed files with 313 additions and 0 deletions
+120
View File
@@ -26859,3 +26859,123 @@ async fn test_end_of_editor_context(cx: &mut TestAppContext) {
assert!(!e.key_context(window, cx).contains("end_of_input"));
});
}
#[gpui::test]
async fn test_next_prev_reference(cx: &mut TestAppContext) {
const CYCLE_POSITIONS: &[&'static str] = &[
indoc! {"
fn foo() {
let ˇabc = 123;
let x = abc + 1;
let y = abc + 2;
let z = abc + 2;
}
"},
indoc! {"
fn foo() {
let abc = 123;
let x = ˇabc + 1;
let y = abc + 2;
let z = abc + 2;
}
"},
indoc! {"
fn foo() {
let abc = 123;
let x = abc + 1;
let y = ˇabc + 2;
let z = abc + 2;
}
"},
indoc! {"
fn foo() {
let abc = 123;
let x = abc + 1;
let y = abc + 2;
let z = ˇabc + 2;
}
"},
];
init_test(cx, |_| {});
let mut cx = EditorLspTestContext::new_rust(
lsp::ServerCapabilities {
references_provider: Some(lsp::OneOf::Left(true)),
..Default::default()
},
cx,
)
.await;
// importantly, the cursor is in the middle
cx.set_state(indoc! {"
fn foo() {
let aˇbc = 123;
let x = abc + 1;
let y = abc + 2;
let z = abc + 2;
}
"});
let reference_ranges = [
lsp::Position::new(1, 8),
lsp::Position::new(2, 12),
lsp::Position::new(3, 12),
lsp::Position::new(4, 12),
]
.map(|start| lsp::Range::new(start, lsp::Position::new(start.line, start.character + 3)));
cx.lsp
.set_request_handler::<lsp::request::References, _, _>(move |params, _cx| async move {
Ok(Some(
reference_ranges
.map(|range| lsp::Location {
uri: params.text_document_position.text_document.uri.clone(),
range,
})
.to_vec(),
))
});
let _move = async |direction, count, cx: &mut EditorLspTestContext| {
cx.update_editor(|editor, window, cx| {
editor.go_to_reference_before_or_after_position(direction, count, window, cx)
})
.unwrap()
.await
.unwrap()
};
_move(Direction::Next, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[1]);
_move(Direction::Next, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[2]);
_move(Direction::Next, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[3]);
// loops back to the start
_move(Direction::Next, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[0]);
// loops back to the end
_move(Direction::Prev, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[3]);
_move(Direction::Prev, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[2]);
_move(Direction::Prev, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[1]);
_move(Direction::Prev, 1, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[0]);
_move(Direction::Next, 3, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[3]);
_move(Direction::Prev, 2, &mut cx).await;
cx.assert_editor_state(CYCLE_POSITIONS[1]);
}