editor: Expand selection to word under cursor before expanding to next enclosing syntax node (#28864)
Closes #27995 For strings in any language and Markdown, `select_larger_syntax_node` will first select the word and then expand from there if: - The cursor is on the word. - The selection is inside the word. It will not select the word and will directly proceed to expand if: - The word is already selected. - Multiple partial words are selected. Todo: - [x] Tests Release Notes: - Fixed `select_larger_syntax_node` to first expand to the word within a string, and then to the larger syntax node.
This commit is contained in:
parent
cb79420773
commit
0d8f77b5de
2 changed files with 220 additions and 1 deletions
|
@ -6309,7 +6309,187 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut TestAppContext) {
|
|||
use mod1::mod2::«{mod3, mod4}ˇ»;
|
||||
|
||||
fn fn_1«ˇ(param1: bool, param2: &str)» {
|
||||
«ˇlet var1 = "text";»
|
||||
let var1 = "«ˇtext»";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[gpui::test]
|
||||
async fn test_select_larger_smaller_syntax_node_for_string(cx: &mut TestAppContext) {
|
||||
init_test(cx, |_| {});
|
||||
|
||||
let language = Arc::new(Language::new(
|
||||
LanguageConfig::default(),
|
||||
Some(tree_sitter_rust::LANGUAGE.into()),
|
||||
));
|
||||
|
||||
let text = r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "hello world";
|
||||
}
|
||||
"#
|
||||
.unindent();
|
||||
|
||||
let buffer = cx.new(|cx| Buffer::local(text, cx).with_language(language, cx));
|
||||
let buffer = cx.new(|cx| MultiBuffer::singleton(buffer, cx));
|
||||
let (editor, cx) = cx.add_window_view(|window, cx| build_editor(buffer, window, cx));
|
||||
|
||||
editor
|
||||
.condition::<crate::EditorEvent>(cx, |editor, cx| !editor.buffer.read(cx).is_parsing(cx))
|
||||
.await;
|
||||
|
||||
// Test 1: Cursor on a letter of a string word
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(3), 17)..DisplayPoint::new(DisplayRow(3), 17)
|
||||
]);
|
||||
});
|
||||
});
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "hˇello world";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "«ˇhello» world";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
// Test 2: Partial selection within a word
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(3), 17)..DisplayPoint::new(DisplayRow(3), 19)
|
||||
]);
|
||||
});
|
||||
});
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "h«elˇ»lo world";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "«ˇhello» world";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
// Test 3: Complete word already selected
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(3), 16)..DisplayPoint::new(DisplayRow(3), 21)
|
||||
]);
|
||||
});
|
||||
});
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "«helloˇ» world";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "«hello worldˇ»";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
// Test 4: Selection spanning across words
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.change_selections(None, window, cx, |s| {
|
||||
s.select_display_ranges([
|
||||
DisplayPoint::new(DisplayRow(3), 19)..DisplayPoint::new(DisplayRow(3), 24)
|
||||
]);
|
||||
});
|
||||
});
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "hel«lo woˇ»rld";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
let var1 = "«ˇhello world»";
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
);
|
||||
});
|
||||
|
||||
// Test 5: Expansion beyond string
|
||||
editor.update_in(cx, |editor, window, cx| {
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
|
||||
assert_text_with_selections(
|
||||
editor,
|
||||
indoc! {r#"
|
||||
use mod1::mod2::{mod3, mod4};
|
||||
|
||||
fn fn_1(param1: bool, param2: &str) {
|
||||
«ˇlet var1 = "hello world";»
|
||||
}
|
||||
"#},
|
||||
cx,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue