Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/tests/test/commands/movement.rs')
-rw-r--r--helix-term/tests/test/commands/movement.rs650
1 files changed, 76 insertions, 574 deletions
diff --git a/helix-term/tests/test/commands/movement.rs b/helix-term/tests/test/commands/movement.rs
index 5868fa49..5be68837 100644
--- a/helix-term/tests/test/commands/movement.rs
+++ b/helix-term/tests/test/commands/movement.rs
@@ -6,7 +6,7 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -14,9 +14,9 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
"no#["|]#
}
}
- "##},
+ "##}),
"<A-e>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -24,10 +24,10 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
\"no\"#[\n|]#
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -35,9 +35,9 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
\"no\"#[\n|]#
}
}
- "},
+ "}),
"<A-e>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -45,11 +45,11 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#[\n|]#
}
- "},
+ "}),
),
// select mode extends
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -57,9 +57,9 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
#["no"|]#
}
}
- "##},
+ "##}),
"v<A-e><A-e>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -67,7 +67,7 @@ async fn test_move_parent_node_end() -> anyhow::Result<()> {
#[\"no\"
}\n|]#
}
- "},
+ "}),
),
];
@@ -84,7 +84,7 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -92,9 +92,9 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
"no#["|]#
}
}
- "##},
+ "##}),
"<A-b>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -102,10 +102,10 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
#[\"|]#no\"
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -113,9 +113,9 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
\"no\"#[\n|]#
}
}
- "},
+ "}),
"<A-b>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -123,10 +123,10 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
\"no\"
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -134,9 +134,9 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
\"no\"
}
}
- "},
+ "}),
"<A-b>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -144,11 +144,11 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
\"no\"
}
}
- "},
+ "}),
),
// select mode extends
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -156,9 +156,9 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
#["no"|]#
}
}
- "##},
+ "##}),
"v<A-b><A-b>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -166,10 +166,10 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
]#\"no\"
}
}
- "},
+ "}),
),
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -177,9 +177,9 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
#["no"|]#
}
}
- "##},
+ "##}),
"v<A-b><A-b><A-b>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -187,7 +187,7 @@ async fn test_move_parent_node_start() -> anyhow::Result<()> {
]#\"no\"
}
}
- "},
+ "}),
),
];
@@ -204,7 +204,7 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
// single cursor stays single cursor, first goes to end of current
// node, then parent
(
- indoc! {r##"
+ helpers::platform_line(indoc! {r##"
fn foo() {
let result = if true {
"yes"
@@ -212,9 +212,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
"no#["|]#
}
}
- "##},
+ "##}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -222,10 +222,10 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"#[|\n]#
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -233,9 +233,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"#[\n|]#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -243,12 +243,12 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#[|\n]#
}
- "},
+ "}),
),
// appending to the end of a line should still look at the current
// line, not the next one
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -256,9 +256,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no#[\"|]#
}
}
- "},
+ "}),
"a<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -266,11 +266,11 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#[\n|]#
}
- "},
+ "}),
),
// before cursor is all whitespace, so insert tab
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -278,9 +278,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
#[\"no\"|]#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -288,12 +288,12 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
#[|\"no\"]#
}
}
- "},
+ "}),
),
// if selection spans multiple lines, it should still only look at the
// line on which the head is
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"
@@ -301,9 +301,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"|]#
}
}
- "},
+ "}),
"a<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -311,10 +311,10 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#[\n|]#
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"
@@ -322,9 +322,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"|]#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"
@@ -332,10 +332,10 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"]#
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
#[l|]#et result = if true {
#(\"yes\"
@@ -343,9 +343,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"|)#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
#[|l]#et result = if true {
#(|\"yes\"
@@ -353,10 +353,10 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\")#
}
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"#[\n|]#
@@ -364,9 +364,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"#(\n|)#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -374,10 +374,10 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#(|\n)#
}
- "},
+ "}),
),
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"|]#
@@ -385,9 +385,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
#(\"no\"|)#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"]#
@@ -395,12 +395,12 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
#(|\"no\")#
}
}
- "},
+ "}),
),
// if any cursors are not preceded by all whitespace, then do the
// smart_tab action
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"\n|]#
@@ -408,9 +408,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no#(\"\n|)#
}
}
- "},
+ "}),
"i<tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
\"yes\"
@@ -418,11 +418,11 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no\"
}#(|\n)#
}
- "},
+ "}),
),
// Ctrl-tab always inserts a tab
(
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[\"yes\"\n|]#
@@ -430,9 +430,9 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no#(\"\n|)#
}
}
- "},
+ "}),
"i<S-tab>",
- indoc! {"\
+ helpers::platform_line(indoc! {"\
fn foo() {
let result = if true {
#[|\"yes\"\n]#
@@ -440,7 +440,7 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
\"no #(|\"\n)#
}
}
- "},
+ "}),
),
];
@@ -450,501 +450,3 @@ async fn test_smart_tab_move_parent_node_end() -> anyhow::Result<()> {
Ok(())
}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn select_all_siblings() -> anyhow::Result<()> {
- let tests = vec![
- // basic tests
- (
- indoc! {r##"
- let foo = bar(#[a|]#, b, c);
- "##},
- "<A-a>",
- indoc! {r##"
- let foo = bar(#[a|]#, #(b|)#, #(c|)#);
- "##},
- ),
- (
- indoc! {r##"
- let a = [
- #[1|]#,
- 2,
- 3,
- 4,
- 5,
- ];
- "##},
- "<A-a>",
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- ),
- // direction is preserved
- (
- indoc! {r##"
- let a = [
- #[|1]#,
- 2,
- 3,
- 4,
- 5,
- ];
- "##},
- "<A-a>",
- indoc! {r##"
- let a = [
- #[|1]#,
- #(|2)#,
- #(|3)#,
- #(|4)#,
- #(|5)#,
- ];
- "##},
- ),
- // can't pick any more siblings - selection stays the same
- (
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- "<A-a>",
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- ),
- // each cursor does the sibling select independently
- (
- indoc! {r##"
- let a = [
- #[1|]#,
- 2,
- 3,
- 4,
- 5,
- ];
-
- let b = [
- #("one"|)#,
- "two",
- "three",
- "four",
- "five",
- ];
- "##},
- "<A-a>",
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
-
- let b = [
- #("one"|)#,
- #("two"|)#,
- #("three"|)#,
- #("four"|)#,
- #("five"|)#,
- ];
- "##},
- ),
- // conflicting sibling selections get normalized. Here, the primary
- // selection would choose every list item, but because the secondary
- // range covers more than one item, the descendent is the entire list,
- // which means the sibling is the assignment. The list item ranges just
- // get normalized out since the list itself becomes selected.
- (
- indoc! {r##"
- let a = [
- #[1|]#,
- 2,
- #(3,
- 4|)#,
- 5,
- ];
- "##},
- "<A-a>",
- indoc! {r##"
- let #(a|)# = #[[
- 1,
- 2,
- 3,
- 4,
- 5,
- ]|]#;
- "##},
- ),
- ];
-
- for test in tests {
- test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
- }
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn select_all_children() -> anyhow::Result<()> {
- let tests = vec![
- // basic tests
- (
- indoc! {r##"
- let foo = bar#[(a, b, c)|]#;
- "##},
- "<A-I>",
- indoc! {r##"
- let foo = bar(#[a|]#, #(b|)#, #(c|)#);
- "##},
- ),
- (
- indoc! {r##"
- let a = #[[
- 1,
- 2,
- 3,
- 4,
- 5,
- ]|]#;
- "##},
- "<A-I>",
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- ),
- // direction is preserved
- (
- indoc! {r##"
- let a = #[|[
- 1,
- 2,
- 3,
- 4,
- 5,
- ]]#;
- "##},
- "<A-I>",
- indoc! {r##"
- let a = [
- #[|1]#,
- #(|2)#,
- #(|3)#,
- #(|4)#,
- #(|5)#,
- ];
- "##},
- ),
- // can't pick any more children - selection stays the same
- (
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- "<A-I>",
- indoc! {r##"
- let a = [
- #[1|]#,
- #(2|)#,
- #(3|)#,
- #(4|)#,
- #(5|)#,
- ];
- "##},
- ),
- // each cursor does the sibling select independently
- (
- indoc! {r##"
- let a = #[|[
- 1,
- 2,
- 3,
- 4,
- 5,
- ]]#;
-
- let b = #([
- "one",
- "two",
- "three",
- "four",
- "five",
- ]|)#;
- "##},
- "<A-I>",
- indoc! {r##"
- let a = [
- #[|1]#,
- #(|2)#,
- #(|3)#,
- #(|4)#,
- #(|5)#,
- ];
-
- let b = [
- #("one"|)#,
- #("two"|)#,
- #("three"|)#,
- #("four"|)#,
- #("five"|)#,
- ];
- "##},
- ),
- ];
-
- for test in tests {
- test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
- }
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn test_select_next_sibling() -> anyhow::Result<()> {
- let tests = vec![
- // basic test
- (
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 #[}|]#
- fn dec(x: usize) -> usize { x - 1 }
- fn ident(x: usize) -> usize { x }
- "##},
- "<A-n>",
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 }
- #[fn dec(x: usize) -> usize { x - 1 }|]#
- fn ident(x: usize) -> usize { x }
- "##},
- ),
- // direction is not preserved and is always forward.
- (
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 #[}|]#
- fn dec(x: usize) -> usize { x - 1 }
- fn ident(x: usize) -> usize { x }
- "##},
- "<A-n><A-;><A-n>",
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 }
- fn dec(x: usize) -> usize { x - 1 }
- #[fn ident(x: usize) -> usize { x }|]#
- "##},
- ),
- ];
-
- for test in tests {
- test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
- }
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn test_select_prev_sibling() -> anyhow::Result<()> {
- let tests = vec![
- // basic test
- (
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 }
- fn dec(x: usize) -> usize { x - 1 }
- #[|f]#n ident(x: usize) -> usize { x }
- "##},
- "<A-p>",
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 }
- #[|fn dec(x: usize) -> usize { x - 1 }]#
- fn ident(x: usize) -> usize { x }
- "##},
- ),
- // direction is not preserved and is always backward.
- (
- indoc! {r##"
- fn inc(x: usize) -> usize { x + 1 }
- fn dec(x: usize) -> usize { x - 1 }
- #[|f]#n ident(x: usize) -> usize { x }
- "##},
- "<A-p><A-;><A-p>",
- indoc! {r##"
- #[|fn inc(x: usize) -> usize { x + 1 }]#
- fn dec(x: usize) -> usize { x - 1 }
- fn ident(x: usize) -> usize { x }
- "##},
- ),
- ];
-
- for test in tests {
- test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
- }
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn match_bracket() -> anyhow::Result<()> {
- let rust_tests = vec![
- // fwd
- (
- indoc! {r##"
- fn foo(x: usize) -> usize { #[x|]# + 1 }
- "##},
- "mm",
- indoc! {r##"
- fn foo(x: usize) -> usize { x + 1 #[}|]#
- "##},
- ),
- // backward
- (
- indoc! {r##"
- fn foo(x: usize) -> usize { #[x|]# + 1 }
- "##},
- "mmmm",
- indoc! {r##"
- fn foo(x: usize) -> usize #[{|]# x + 1 }
- "##},
- ),
- // avoid false positive inside string literal
- (
- indoc! {r##"
- fn foo() -> &'static str { "(hello#[ |]#world)" }
- "##},
- "mm",
- indoc! {r##"
- fn foo() -> &'static str { "(hello world)#["|]# }
- "##},
- ),
- // make sure matching on quotes works
- (
- indoc! {r##"
- fn foo() -> &'static str { "(hello#[ |]#world)" }
- "##},
- "mm",
- indoc! {r##"
- fn foo() -> &'static str { "(hello world)#["|]# }
- "##},
- ),
- // .. on both ends
- (
- indoc! {r##"
- fn foo() -> &'static str { "(hello#[ |]#world)" }
- "##},
- "mmmm",
- indoc! {r##"
- fn foo() -> &'static str { #["|]#(hello world)" }
- "##},
- ),
- // match on siblings nodes
- (
- indoc! {r##"
- fn foo(bar: Option<usize>) -> usize {
- match bar {
- Some(b#[a|]#r) => bar,
- None => 42,
- }
- }
- "##},
- "mmmm",
- indoc! {r##"
- fn foo(bar: Option<usize>) -> usize {
- match bar {
- Some#[(|]#bar) => bar,
- None => 42,
- }
- }
- "##},
- ),
- // gracefully handle multiple sibling brackets (usally for errors/incomplete syntax trees)
- // in the past we selected the first > instead of the second > here
- (
- indoc! {r##"
- fn foo() {
- foo::<b#[a|]#r<>>
- }
- "##},
- "mm",
- indoc! {r##"
- fn foo() {
- foo::<bar<>#[>|]#
- }
- "##},
- ),
- // named node with 2 or more children
- (
- indoc! {r##"
- use a::#[{|]#
- b::{c, d, e, f, g},
- h, i, j, k, l, m, n,
- };
- "##},
- "mm",
- indoc! {r##"
- use a::{
- b::{c, d, e, f, g},
- h, i, j, k, l, m, n,
- #[}|]#;
- "##},
- ),
- ];
-
- let python_tests = vec![
- // python quotes have a slightly more complex syntax tree
- // that triggerd a bug in an old implementation so we test
- // them here
- (
- indoc! {r##"
- foo_python = "mm does not#[ |]#work on this string"
- "##},
- "mm",
- indoc! {r##"
- foo_python = "mm does not work on this string#["|]#
- "##},
- ),
- (
- indoc! {r##"
- foo_python = "mm does not#[ |]#work on this string"
- "##},
- "mmmm",
- indoc! {r##"
- foo_python = #["|]#mm does not work on this string"
- "##},
- ),
- ];
-
- for test in rust_tests {
- println!("{test:?}");
- test_with_config(AppBuilder::new().with_file("foo.rs", None), test).await?;
- }
- for test in python_tests {
- println!("{test:?}");
- test_with_config(AppBuilder::new().with_file("foo.py", None), test).await?;
- }
-
- Ok(())
-}