@@ -8591,10 +8591,10 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut TestAppContext) {
assert_text_with_selections(
editor,
indoc! {r#"
- use mod1::mod2::{mod3, mo«ˇ»d4};
+ use mod1::mod2::{mod3, moˇd4};
fn fn_1(para«ˇm1: bool, pa»ram2: &str) {
- let var1 = "te«ˇ»xt";
+ let var1 = "teˇxt";
}
"#},
cx,
@@ -8609,10 +8609,10 @@ async fn test_select_larger_smaller_syntax_node(cx: &mut TestAppContext) {
assert_text_with_selections(
editor,
indoc! {r#"
- use mod1::mod2::{mod3, mo«ˇ»d4};
+ use mod1::mod2::{mod3, moˇd4};
fn fn_1(para«ˇm1: bool, pa»ram2: &str) {
- let var1 = "te«ˇ»xt";
+ let var1 = "teˇxt";
}
"#},
cx,
@@ -8716,6 +8716,184 @@ async fn test_select_larger_syntax_node_for_cursor_at_end(cx: &mut TestAppContex
});
}
+#[gpui::test]
+async fn test_select_larger_syntax_node_for_cursor_at_symbol(cx: &mut TestAppContext) {
+ init_test(cx, |_| {});
+
+ let language = Arc::new(Language::new(
+ LanguageConfig {
+ name: "JavaScript".into(),
+ ..Default::default()
+ },
+ Some(tree_sitter_typescript::LANGUAGE_TSX.into()),
+ ));
+
+ let text = r#"
+ let a = {
+ key: "value",
+ };
+ "#
+ .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 case 1: Cursor after '{'
+ editor.update_in(cx, |editor, window, cx| {
+ editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(0), 9)..DisplayPoint::new(DisplayRow(0), 9)
+ ]);
+ });
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = {ˇ
+ key: "value",
+ };
+ "#},
+ cx,
+ );
+ });
+ editor.update_in(cx, |editor, window, cx| {
+ editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = «ˇ{
+ key: "value",
+ }»;
+ "#},
+ cx,
+ );
+ });
+
+ // Test case 2: Cursor after ':'
+ editor.update_in(cx, |editor, window, cx| {
+ editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 8)..DisplayPoint::new(DisplayRow(1), 8)
+ ]);
+ });
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = {
+ key:ˇ "value",
+ };
+ "#},
+ cx,
+ );
+ });
+ editor.update_in(cx, |editor, window, cx| {
+ editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = {
+ «ˇkey: "value"»,
+ };
+ "#},
+ cx,
+ );
+ });
+ editor.update_in(cx, |editor, window, cx| {
+ editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = «ˇ{
+ key: "value",
+ }»;
+ "#},
+ cx,
+ );
+ });
+
+ // Test case 3: Cursor after ','
+ editor.update_in(cx, |editor, window, cx| {
+ editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(1), 17)..DisplayPoint::new(DisplayRow(1), 17)
+ ]);
+ });
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = {
+ key: "value",ˇ
+ };
+ "#},
+ cx,
+ );
+ });
+ editor.update_in(cx, |editor, window, cx| {
+ editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = «ˇ{
+ key: "value",
+ }»;
+ "#},
+ cx,
+ );
+ });
+
+ // Test case 4: Cursor after ';'
+ editor.update_in(cx, |editor, window, cx| {
+ editor.change_selections(SelectionEffects::no_scroll(), window, cx, |s| {
+ s.select_display_ranges([
+ DisplayPoint::new(DisplayRow(2), 2)..DisplayPoint::new(DisplayRow(2), 2)
+ ]);
+ });
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ let a = {
+ key: "value",
+ };ˇ
+ "#},
+ cx,
+ );
+ });
+ editor.update_in(cx, |editor, window, cx| {
+ editor.select_larger_syntax_node(&SelectLargerSyntaxNode, window, cx);
+ });
+ editor.update(cx, |editor, cx| {
+ assert_text_with_selections(
+ editor,
+ indoc! {r#"
+ «ˇlet a = {
+ key: "value",
+ };
+ »"#},
+ cx,
+ );
+ });
+}
+
#[gpui::test]
async fn test_select_larger_smaller_syntax_node_for_string(cx: &mut TestAppContext) {
init_test(cx, |_| {});
@@ -20,7 +20,7 @@ use multi_buffer::ToPoint;
use pretty_assertions::assert_eq;
use project::{Project, project_settings::DiagnosticSeverity};
use ui::{App, BorrowAppContext, px};
-use util::test::{marked_text_offsets, marked_text_ranges};
+use util::test::{generate_marked_text, marked_text_offsets, marked_text_ranges};
#[cfg(test)]
#[ctor::ctor]
@@ -104,13 +104,14 @@ pub fn assert_text_with_selections(
marked_text: &str,
cx: &mut Context<Editor>,
) {
- let (unmarked_text, text_ranges) = marked_text_ranges(marked_text, true);
+ let (unmarked_text, _text_ranges) = marked_text_ranges(marked_text, true);
assert_eq!(editor.text(cx), unmarked_text, "text doesn't match");
- assert_eq!(
- editor.selections.ranges(cx),
- text_ranges,
- "selections don't match",
+ let actual = generate_marked_text(
+ &editor.text(cx),
+ &editor.selections.ranges(cx),
+ marked_text.contains("«"),
);
+ assert_eq!(actual, marked_text, "Selections don't match");
}
// RA thinks this is dead code even though it is used in a whole lot of tests