specify direction for select_prev_sibling and select_next_sibling (#10542)
* specify direction for select_prev_sibling and select_next_sibling * fix failing integration-test
This commit is contained in:
parent
e18b772654
commit
89a9f2be78
3 changed files with 117 additions and 18 deletions
|
@ -1,4 +1,4 @@
|
|||
use crate::{syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};
|
||||
use crate::{movement::Direction, syntax::TreeCursor, Range, RopeSlice, Selection, Syntax};
|
||||
|
||||
pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
||||
let cursor = &mut syntax.walk();
|
||||
|
@ -25,19 +25,31 @@ pub fn expand_selection(syntax: &Syntax, text: RopeSlice, selection: Selection)
|
|||
}
|
||||
|
||||
pub fn shrink_selection(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
||||
select_node_impl(syntax, text, selection, |cursor| {
|
||||
select_node_impl(
|
||||
syntax,
|
||||
text,
|
||||
selection,
|
||||
|cursor| {
|
||||
cursor.goto_first_child();
|
||||
})
|
||||
},
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn select_next_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
||||
select_node_impl(syntax, text, selection, |cursor| {
|
||||
select_node_impl(
|
||||
syntax,
|
||||
text,
|
||||
selection,
|
||||
|cursor| {
|
||||
while !cursor.goto_next_sibling() {
|
||||
if !cursor.goto_parent() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
Some(Direction::Forward),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn select_all_siblings(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
||||
|
@ -81,13 +93,19 @@ fn select_children<'n>(
|
|||
}
|
||||
|
||||
pub fn select_prev_sibling(syntax: &Syntax, text: RopeSlice, selection: Selection) -> Selection {
|
||||
select_node_impl(syntax, text, selection, |cursor| {
|
||||
select_node_impl(
|
||||
syntax,
|
||||
text,
|
||||
selection,
|
||||
|cursor| {
|
||||
while !cursor.goto_prev_sibling() {
|
||||
if !cursor.goto_parent() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
Some(Direction::Backward),
|
||||
)
|
||||
}
|
||||
|
||||
fn select_node_impl<F>(
|
||||
|
@ -95,6 +113,7 @@ fn select_node_impl<F>(
|
|||
text: RopeSlice,
|
||||
selection: Selection,
|
||||
motion: F,
|
||||
direction: Option<Direction>,
|
||||
) -> Selection
|
||||
where
|
||||
F: Fn(&mut TreeCursor),
|
||||
|
@ -113,6 +132,6 @@ where
|
|||
let from = text.byte_to_char(node.start_byte());
|
||||
let to = text.byte_to_char(node.end_byte());
|
||||
|
||||
Range::new(from, to).with_direction(range.direction())
|
||||
Range::new(from, to).with_direction(direction.unwrap_or_else(|| range.direction()))
|
||||
})
|
||||
}
|
||||
|
|
|
@ -726,3 +726,83 @@ async fn select_all_children() -> anyhow::Result<()> {
|
|||
|
||||
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(())
|
||||
}
|
||||
|
|
|
@ -666,7 +666,7 @@ async fn tree_sitter_motions_work_across_injections() -> anyhow::Result<()> {
|
|||
(
|
||||
"<script>let #[|x]# = 1;</script>",
|
||||
"<A-n>",
|
||||
"<script>let x #[|=]# 1;</script>",
|
||||
"<script>let x #[=|]# 1;</script>",
|
||||
),
|
||||
)
|
||||
.await?;
|
||||
|
|
Loading…
Add table
Reference in a new issue