Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-term/tests/test/movement.rs')
-rw-r--r--helix-term/tests/test/movement.rs728
1 files changed, 0 insertions, 728 deletions
diff --git a/helix-term/tests/test/movement.rs b/helix-term/tests/test/movement.rs
deleted file mode 100644
index 062d3796..00000000
--- a/helix-term/tests/test/movement.rs
+++ /dev/null
@@ -1,728 +0,0 @@
-use super::*;
-
-#[tokio::test(flavor = "multi_thread")]
-async fn insert_mode_cursor_position() -> anyhow::Result<()> {
- test(TestCase {
- in_text: String::new(),
- in_selection: Selection::single(0, 0),
- in_keys: "i".into(),
- out_text: String::new(),
- out_selection: Selection::single(0, 0),
- line_feed_handling: LineFeedHandling::AsIs,
- })
- .await?;
-
- test(("#[\n|]#", "i", "#[|\n]#")).await?;
- test(("#[\n|]#", "i<esc>", "#[|\n]#")).await?;
- test(("#[\n|]#", "i<esc>i", "#[|\n]#")).await?;
-
- Ok(())
-}
-
-/// Range direction is preserved when escaping insert mode to normal
-#[tokio::test(flavor = "multi_thread")]
-async fn insert_to_normal_mode_cursor_position() -> anyhow::Result<()> {
- test(("#[f|]#oo\n", "vll<A-;><esc>", "#[|foo]#\n")).await?;
- test((
- indoc! {"\
- #[f|]#oo
- #(b|)#ar"
- },
- "vll<A-;><esc>",
- indoc! {"\
- #[|foo]#
- #(|bar)#"
- },
- ))
- .await?;
-
- test((
- indoc! {"\
- #[f|]#oo
- #(b|)#ar"
- },
- "a",
- indoc! {"\
- #[fo|]#o
- #(ba|)#r"
- },
- ))
- .await?;
-
- test((
- indoc! {"\
- #[f|]#oo
- #(b|)#ar"
- },
- "a<esc>",
- indoc! {"\
- #[f|]#oo
- #(b|)#ar"
- },
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn surround_by_character() -> anyhow::Result<()> {
- // Only pairs matching the passed character count
- test((
- "(so [many {go#[o|]#d} text] here)",
- "mi{",
- "(so [many {#[good|]#} text] here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "mi[",
- "(so [#[many {good} text|]#] here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "mi(",
- "(#[so [many {good} text] here|]#)",
- ))
- .await?;
-
- // Works with characters that aren't pairs too
- test((
- "'so 'many 'go#[o|]#d' text' here'",
- "mi'",
- "'so 'many '#[good|]#' text' here'",
- ))
- .await?;
- test((
- "'so 'many 'go#[o|]#d' text' here'",
- "2mi'",
- "'so '#[many 'good' text|]#' here'",
- ))
- .await?;
- test((
- "'so \"many 'go#[o|]#d' text\" here'",
- "mi\"",
- "'so \"#[many 'good' text|]#\" here'",
- ))
- .await?;
-
- // Selection direction is preserved
- test((
- "(so [many {go#[|od]#} text] here)",
- "mi{",
- "(so [many {#[|good]#} text] here)",
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn surround_inside_pair() -> anyhow::Result<()> {
- // Works at first character of buffer
- // TODO: Adjust test when opening pair failure is fixed
- test(("#[(|]#something)", "mim", "#[(|]#something)")).await?;
-
- // Inside a valid pair selects pair
- test(("some (#[t|]#ext) here", "mim", "some (#[text|]#) here")).await?;
-
- // On pair character selects pair
- // TODO: Opening pair character is a known failure case that needs addressing
- // test(("some #[(|]#text) here", "mim", "some (#[text|]#) here")).await?;
- test(("some (text#[)|]# here", "mim", "some (#[text|]#) here")).await?;
-
- // No valid pair does nothing
- test(("so#[m|]#e (text) here", "mim", "so#[m|]#e (text) here")).await?;
-
- // Count skips to outer pairs
- test((
- "(so (many (go#[o|]#d) text) here)",
- "1mim",
- "(so (many (#[good|]#) text) here)",
- ))
- .await?;
- test((
- "(so (many (go#[o|]#d) text) here)",
- "2mim",
- "(so (#[many (good) text|]#) here)",
- ))
- .await?;
- test((
- "(so (many (go#[o|]#d) text) here)",
- "3mim",
- "(#[so (many (good) text) here|]#)",
- ))
- .await?;
-
- // Matching pairs outside selection don't match
- test((
- "((so)((many) go#[o|]#d (text))(here))",
- "mim",
- "((so)(#[(many) good (text)|]#)(here))",
- ))
- .await?;
- test((
- "((so)((many) go#[o|]#d (text))(here))",
- "2mim",
- "(#[(so)((many) good (text))(here)|]#)",
- ))
- .await?;
-
- // Works with mixed braces
- test((
- "(so [many {go#[o|]#d} text] here)",
- "mim",
- "(so [many {#[good|]#} text] here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "2mim",
- "(so [#[many {good} text|]#] here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "3mim",
- "(#[so [many {good} text] here|]#)",
- ))
- .await?;
-
- // Selection direction is preserved
- test((
- "(so [many {go#[|od]#} text] here)",
- "mim",
- "(so [many {#[|good]#} text] here)",
- ))
- .await?;
- test((
- "(so [many {go#[|od]#} text] here)",
- "2mim",
- "(so [#[|many {good} text]#] here)",
- ))
- .await?;
- test((
- "(so [many {go#[|od]#} text] here)",
- "3mim",
- "(#[|so [many {good} text] here]#)",
- ))
- .await?;
-
- // Only pairs outside of full selection range are considered
- test((
- "(so (many (go#[od) |]#text) here)",
- "mim",
- "(so (#[many (good) text|]#) here)",
- ))
- .await?;
- test((
- "(so (many#[ (go|]#od) text) here)",
- "mim",
- "(so (#[many (good) text|]#) here)",
- ))
- .await?;
- test((
- "(so#[ (many (go|]#od) text) here)",
- "mim",
- "(#[so (many (good) text) here|]#)",
- ))
- .await?;
- test((
- "(so (many (go#[od) text) |]#here)",
- "mim",
- "(#[so (many (good) text) here|]#)",
- ))
- .await?;
-
- // Works with multiple cursors
- test((
- "(so (many (good) text) #[he|]#re\nso (many (good) text) #(|he)#re)",
- "mim",
- "(#[so (many (good) text) here\nso (many (good) text) here|]#)",
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn surround_around_pair() -> anyhow::Result<()> {
- // Works at first character of buffer
- // TODO: Adjust test when opening pair failure is fixed
- test(("#[(|]#something)", "mam", "#[(|]#something)")).await?;
-
- // Inside a valid pair selects pair
- test(("some (#[t|]#ext) here", "mam", "some #[(text)|]# here")).await?;
-
- // On pair character selects pair
- // TODO: Opening pair character is a known failure case that needs addressing
- // test(("some #[(|]#text) here", "mam", "some #[(text)|]# here")).await?;
- test(("some (text#[)|]# here", "mam", "some #[(text)|]# here")).await?;
-
- // No valid pair does nothing
- test(("so#[m|]#e (text) here", "mam", "so#[m|]#e (text) here")).await?;
-
- // Count skips to outer pairs
- test((
- "(so (many (go#[o|]#d) text) here)",
- "1mam",
- "(so (many #[(good)|]# text) here)",
- ))
- .await?;
- test((
- "(so (many (go#[o|]#d) text) here)",
- "2mam",
- "(so #[(many (good) text)|]# here)",
- ))
- .await?;
- test((
- "(so (many (go#[o|]#d) text) here)",
- "3mam",
- "#[(so (many (good) text) here)|]#",
- ))
- .await?;
-
- // Matching pairs outside selection don't match
- test((
- "((so)((many) go#[o|]#d (text))(here))",
- "mam",
- "((so)#[((many) good (text))|]#(here))",
- ))
- .await?;
- test((
- "((so)((many) go#[o|]#d (text))(here))",
- "2mam",
- "#[((so)((many) good (text))(here))|]#",
- ))
- .await?;
-
- // Works with mixed braces
- test((
- "(so [many {go#[o|]#d} text] here)",
- "mam",
- "(so [many #[{good}|]# text] here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "2mam",
- "(so #[[many {good} text]|]# here)",
- ))
- .await?;
- test((
- "(so [many {go#[o|]#d} text] here)",
- "3mam",
- "#[(so [many {good} text] here)|]#",
- ))
- .await?;
-
- // Selection direction is preserved
- test((
- "(so [many {go#[|od]#} text] here)",
- "mam",
- "(so [many #[|{good}]# text] here)",
- ))
- .await?;
- test((
- "(so [many {go#[|od]#} text] here)",
- "2mam",
- "(so #[|[many {good} text]]# here)",
- ))
- .await?;
- test((
- "(so [many {go#[|od]#} text] here)",
- "3mam",
- "#[|(so [many {good} text] here)]#",
- ))
- .await?;
-
- // Only pairs outside of full selection range are considered
- test((
- "(so (many (go#[od) |]#text) here)",
- "mam",
- "(so #[(many (good) text)|]# here)",
- ))
- .await?;
- test((
- "(so (many#[ (go|]#od) text) here)",
- "mam",
- "(so #[(many (good) text)|]# here)",
- ))
- .await?;
- test((
- "(so#[ (many (go|]#od) text) here)",
- "mam",
- "#[(so (many (good) text) here)|]#",
- ))
- .await?;
- test((
- "(so (many (go#[od) text) |]#here)",
- "mam",
- "#[(so (many (good) text) here)|]#",
- ))
- .await?;
-
- // Works with multiple cursors
- test((
- "(so (many (good) text) #[he|]#re\nso (many (good) text) #(|he)#re)",
- "mam",
- "#[(so (many (good) text) here\nso (many (good) text) here)|]#",
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn match_around_closest_ts() -> anyhow::Result<()> {
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- r#"fn main() {testing!{"f#[|oo]#)"};}"#,
- "mam",
- r#"fn main() {testing!{#[|"foo)"]#};}"#,
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- r##"fn main() { let _ = ("#[|1]#23", "#(|1)#23"); } "##,
- "3mam",
- r##"fn main() #[|{ let _ = ("123", "123"); }]# "##,
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- r##" fn main() { let _ = ("12#[|3", "12]#3"); } "##,
- "1mam",
- r##" fn main() { let _ = #[|("123", "123")]#; } "##,
- ),
- )
- .await?;
-
- Ok(())
-}
-
-/// Ensure the very initial cursor in an opened file is the width of
-/// the first grapheme
-#[tokio::test(flavor = "multi_thread")]
-async fn cursor_position_newly_opened_file() -> anyhow::Result<()> {
- let test = |content: &str, expected_sel: Selection| -> anyhow::Result<()> {
- let file = helpers::temp_file_with_contents(content)?;
- let mut app = helpers::AppBuilder::new()
- .with_file(file.path(), None)
- .build()?;
-
- let (view, doc) = helix_view::current!(app.editor);
- let sel = doc.selection(view.id).clone();
- assert_eq!(expected_sel, sel);
-
- Ok(())
- };
-
- test("foo", Selection::single(0, 1))?;
- test("๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ foo", Selection::single(0, 7))?;
- test("", Selection::single(0, 0))?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn cursor_position_append_eof() -> anyhow::Result<()> {
- // Selection is forwards
- test(("#[foo|]#", "abar<esc>", "#[foobar|]#\n")).await?;
-
- // Selection is backwards
- test(("#[|foo]#", "abar<esc>", "#[foobar|]#\n")).await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn select_mode_tree_sitter_next_function_is_union_of_objects() -> anyhow::Result<()> {
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- indoc! {"\
- #[/|]#// Increments
- fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }
- "},
- "]fv]f",
- indoc! {"\
- /// Increments
- #[fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }|]#
- "},
- ),
- )
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn select_mode_tree_sitter_prev_function_unselects_object() -> anyhow::Result<()> {
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- indoc! {"\
- /// Increments
- #[fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }|]#
- "},
- "v[f",
- indoc! {"\
- /// Increments
- #[fn inc(x: usize) -> usize { x + 1 }|]#
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }
- "},
- ),
- )
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn select_mode_tree_sitter_prev_function_goes_backwards_to_object() -> anyhow::Result<()> {
- // Note: the anchor stays put and the head moves back.
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- indoc! {"\
- /// Increments
- fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }
- /// Identity
- #[fn ident(x: usize) -> usize { x }|]#
- "},
- "v[f",
- indoc! {"\
- /// Increments
- fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- #[|fn dec(x: usize) -> usize { x - 1 }
- /// Identity
- ]#fn ident(x: usize) -> usize { x }
- "},
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.rs", None),
- (
- indoc! {"\
- /// Increments
- fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }
- /// Identity
- #[fn ident(x: usize) -> usize { x }|]#
- "},
- "v[f[f",
- indoc! {"\
- /// Increments
- #[|fn inc(x: usize) -> usize { x + 1 }
- /// Decrements
- fn dec(x: usize) -> usize { x - 1 }
- /// Identity
- ]#fn ident(x: usize) -> usize { x }
- "},
- ),
- )
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn find_char_line_ending() -> anyhow::Result<()> {
- test((
- indoc! {
- "\
- one
- #[|t]#wo
- three"
- },
- "T<ret>gll2f<ret>",
- indoc! {
- "\
- one
- two#[
- |]#three"
- },
- ))
- .await?;
-
- test((
- indoc! {
- "\
- #[|o]#ne
- two
- three"
- },
- "f<ret>2t<ret>ghT<ret>F<ret>",
- indoc! {
- "\
- one#[|
- t]#wo
- three"
- },
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn test_surround_replace() -> anyhow::Result<()> {
- test((
- indoc! {"\
- (#[|a]#)
- "},
- "mrm{",
- indoc! {"\
- {#[|a]#}
- "},
- ))
- .await?;
-
- test((
- indoc! {"\
- (#[a|]#)
- "},
- "mrm{",
- indoc! {"\
- {#[a|]#}
- "},
- ))
- .await?;
-
- test((
- indoc! {"\
- {{
-
- #(}|)#
- #[}|]#
- "},
- "mrm)",
- indoc! {"\
- ((
-
- #()|)#
- #[)|]#
- "},
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn test_surround_delete() -> anyhow::Result<()> {
- test((
- indoc! {"\
- (#[|a]#)
- "},
- "mdm",
- indoc! {"\
- #[|a]#
- "},
- ))
- .await?;
-
- test((
- indoc! {"\
- (#[a|]#)
- "},
- "mdm",
- indoc! {"\
- #[a|]#
- "},
- ))
- .await?;
-
- test((
- indoc! {"\
- {{
-
- #(}|)#
- #[}|]#
- "},
- "mdm",
- "\n\n#(\n|)##[\n|]#",
- ))
- .await?;
-
- Ok(())
-}
-
-#[tokio::test(flavor = "multi_thread")]
-async fn tree_sitter_motions_work_across_injections() -> anyhow::Result<()> {
- test_with_config(
- AppBuilder::new().with_file("foo.html", None),
- (
- "<script>let #[|x]# = 1;</script>",
- "<A-o>",
- "<script>let #[|x = 1]#;</script>",
- ),
- )
- .await?;
-
- // When the full injected layer is selected, expand_selection jumps to
- // a more shallow layer.
- test_with_config(
- AppBuilder::new().with_file("foo.html", None),
- (
- "<script>#[|let x = 1;]#</script>",
- "<A-o>",
- "#[|<script>let x = 1;</script>]#",
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.html", None),
- (
- "<script>let #[|x = 1]#;</script>",
- "<A-i>",
- "<script>let #[|x]# = 1;</script>",
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.html", None),
- (
- "<script>let #[|x]# = 1;</script>",
- "<A-n>",
- "<script>let x #[=|]# 1;</script>",
- ),
- )
- .await?;
-
- test_with_config(
- AppBuilder::new().with_file("foo.html", None),
- (
- "<script>let #[|x]# = 1;</script>",
- "<A-p>",
- "<script>#[|let]# x = 1;</script>",
- ),
- )
- .await?;
-
- Ok(())
-}