Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'helix-core/src/textobject.rs')
| -rw-r--r-- | helix-core/src/textobject.rs | 52 |
1 files changed, 19 insertions, 33 deletions
diff --git a/helix-core/src/textobject.rs b/helix-core/src/textobject.rs index 008228f4..76c6d103 100644 --- a/helix-core/src/textobject.rs +++ b/helix-core/src/textobject.rs @@ -1,14 +1,15 @@ use std::fmt::Display; use ropey::RopeSlice; +use tree_sitter::{Node, QueryCursor}; use crate::chars::{categorize_char, char_is_whitespace, CharCategory}; use crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary}; use crate::line_ending::rope_is_line_ending; use crate::movement::Direction; -use crate::syntax; +use crate::surround; +use crate::syntax::LanguageConfiguration; use crate::Range; -use crate::{surround, Syntax}; fn find_word_boundary(slice: RopeSlice, mut pos: usize, direction: Direction, long: bool) -> usize { use CharCategory::{Eol, Whitespace}; @@ -198,28 +199,25 @@ pub fn textobject_paragraph( } pub fn textobject_pair_surround( - syntax: Option<&Syntax>, slice: RopeSlice, range: Range, textobject: TextObject, ch: char, count: usize, ) -> Range { - textobject_pair_surround_impl(syntax, slice, range, textobject, Some(ch), count) + textobject_pair_surround_impl(slice, range, textobject, Some(ch), count) } pub fn textobject_pair_surround_closest( - syntax: Option<&Syntax>, slice: RopeSlice, range: Range, textobject: TextObject, count: usize, ) -> Range { - textobject_pair_surround_impl(syntax, slice, range, textobject, None, count) + textobject_pair_surround_impl(slice, range, textobject, None, count) } fn textobject_pair_surround_impl( - syntax: Option<&Syntax>, slice: RopeSlice, range: Range, textobject: TextObject, @@ -228,24 +226,13 @@ fn textobject_pair_surround_impl( ) -> Range { let pair_pos = match ch { Some(ch) => surround::find_nth_pairs_pos(slice, ch, range, count), - None => surround::find_nth_closest_pairs_pos(syntax, slice, range, count), + // Automatically find the closest surround pairs + None => surround::find_nth_closest_pairs_pos(slice, range, count), }; pair_pos .map(|(anchor, head)| match textobject { - TextObject::Inside => { - if anchor < head { - Range::new(next_grapheme_boundary(slice, anchor), head) - } else { - Range::new(anchor, next_grapheme_boundary(slice, head)) - } - } - TextObject::Around => { - if anchor < head { - Range::new(anchor, next_grapheme_boundary(slice, head)) - } else { - Range::new(next_grapheme_boundary(slice, anchor), head) - } - } + TextObject::Inside => Range::new(next_grapheme_boundary(slice, anchor), head), + TextObject::Around => Range::new(anchor, next_grapheme_boundary(slice, head)), TextObject::Movement => unreachable!(), }) .unwrap_or(range) @@ -259,18 +246,18 @@ pub fn textobject_treesitter( range: Range, textobject: TextObject, object_name: &str, - syntax: &Syntax, - loader: &syntax::Loader, + slice_tree: Node, + lang_config: &LanguageConfiguration, _count: usize, ) -> Range { - let root = syntax.tree().root_node(); - let textobject_query = loader.textobject_query(syntax.root_language()); let get_range = move || -> Option<Range> { let byte_pos = slice.char_to_byte(range.cursor(slice)); let capture_name = format!("{}.{}", object_name, textobject); // eg. function.inner - let node = textobject_query? - .capture_nodes(&capture_name, &root, slice)? + let mut cursor = QueryCursor::new(); + let node = lang_config + .textobject_query()? + .capture_nodes(&capture_name, slice_tree, slice, &mut cursor)? .filter(|node| node.byte_range().contains(&byte_pos)) .min_by_key(|node| node.byte_range().len())?; @@ -438,7 +425,7 @@ mod test { let text = Rope::from(s.as_str()); let selection = selection .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 1)); - let actual = crate::test::plain(s.as_ref(), &selection); + let actual = crate::test::plain(&s, selection); assert_eq!(actual, expected, "\nbefore: `{:?}`", before); } } @@ -461,7 +448,7 @@ mod test { let text = Rope::from(s.as_str()); let selection = selection .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Inside, 2)); - let actual = crate::test::plain(s.as_ref(), &selection); + let actual = crate::test::plain(&s, selection); assert_eq!(actual, expected, "\nbefore: `{:?}`", before); } } @@ -492,7 +479,7 @@ mod test { let text = Rope::from(s.as_str()); let selection = selection .transform(|r| textobject_paragraph(text.slice(..), r, TextObject::Around, 1)); - let actual = crate::test::plain(s.as_ref(), &selection); + let actual = crate::test::plain(&s, selection); assert_eq!(actual, expected, "\nbefore: `{:?}`", before); } } @@ -575,8 +562,7 @@ mod test { let slice = doc.slice(..); for &case in scenario { let (pos, objtype, expected_range, ch, count) = case; - let result = - textobject_pair_surround(None, slice, Range::point(pos), objtype, ch, count); + let result = textobject_pair_surround(slice, Range::point(pos), objtype, ch, count); assert_eq!( result, expected_range.into(), |