From 12d9fcee0e84657f3c0788dfc7bc1881249a4e95 Mon Sep 17 00:00:00 2001
From: Nikita Revenco <154856872+nikitarevenco@users.noreply.github.com>
Date: Tue, 12 Nov 2024 16:20:38 +0000
Subject: [PATCH] feat: add function to get next tag's position and test for it
---
helix-core/src/surround.rs | 147 ++++++++++++++++++++++++-------------
helix-term/src/commands.rs | 11 ++-
2 files changed, 104 insertions(+), 54 deletions(-)
diff --git a/helix-core/src/surround.rs b/helix-core/src/surround.rs
index e3d2d2253..7c3394e7e 100644
--- a/helix-core/src/surround.rs
+++ b/helix-core/src/surround.rs
@@ -154,6 +154,29 @@ fn find_nth_closest_pairs_plain(
Err(Error::PairNotFound)
}
+/// Find the position of surrounding tags around cursor
+/// `n` will skip n - 1 tags (e.g. n=2 will discard only the first tag found)
+/// and keep looking
+// pub fn find_nth_tag_pos(
+// text: RopeSlice,
+// range: Range,
+// n: usize,
+// ) -> Result<((usize, usize), (usize, usize))> {
+// // 7 is the minimum possible length for a tag, e.g. .
+// if text.len_chars() < 7 {
+// return Err(Error::PairNotFound);
+// }
+
+// if range.to() >= text.len_chars() {
+// return Err(Error::RangeExceedsText);
+// }
+
+// let cursor_position = range.cursor(text);
+
+// let open = ();
+// let close = ();
+// }
+
/// Find the position of surround pairs of `ch` which can be either a closing
/// or opening pair. `n` will skip n - 1 pairs (eg. n=2 will discard (only)
/// the first pair found and keep looking)
@@ -314,54 +337,82 @@ pub fn get_surround_pos(
Ok(change_pos)
}
-fn find_nth_close_tag(
- text: RopeSlice,
- tag: &str,
- mut pos: usize,
- n: usize,
-) -> Result<(Vec, Vec)> {
- // if text.len_chars() < 2 {
- // return Err(Error::PairNotFound);
- // }
- // if range.to() >= text.len_chars() {
- // return Err(Error::RangeExceedsText);
- // }
- //
- Ok((vec![4, 7], vec![10, 13]))
-}
-
/// like get_surround_pos, but for Tags
pub fn get_surround_pos_tag(
text: RopeSlice,
selection: &Selection,
- tag: &str,
skip: usize,
-) -> Result> {
- let mut change_pos = Vec::new();
+) -> Result> {
+ // // let change_pos: Vec<(usize, usize)> = vec![(4, 10), (13, 20), (24, 30), (33, 40)];
+ // let mut change_pos = Vec::new();
+
+ // // for &range in selection {
+ // // let (start1, end1, start2, end2) = {
+ // // let cursor_pos = range.cursor(text);
+ // // // let range_raw = find_nth_close_tag(text, cursor_pos, skip).unwrap();
+
+ // // let first = range_raw.0;
+ // // let second = range_raw.1;
+ // // let first_1 = first.first().unwrap();
+ // // let first_2 = second.last().unwrap();
+ // // let second_1 = first.first().unwrap();
+ // // let second_2 = second.last().unwrap();
+ // // let range_first = Range::new(*first_1, *first_2);
+ // // let range_last = Range::new(*second_1, *second_2);
+ // // (
+ // // range_first.from(),
+ // // range_first.to(),
+ // // range_last.from(),
+ // // range_last.to(),
+ // // )
+ // // };
+ // // change_pos.push((start1, end1));
+ // // change_pos.push((start2, end2));
+ // // }
+ Ok(vec![(14, 24)])
+}
- for &range in selection {
- let (start1, end1, start2, end2) = {
- let pos = range.cursor(text);
- let range_raw = find_nth_close_tag(text, tag, pos, skip).unwrap();
-
- let first = range_raw.0;
- let second = range_raw.1;
- let first_1 = first.first().unwrap();
- let first_2 = second.last().unwrap();
- let second_1 = first.first().unwrap();
- let second_2 = second.last().unwrap();
- let range_first = Range::new(*first_1, *first_2);
- let range_last = Range::new(*second_1, *second_2);
- (
- range_first.from(),
- range_first.to(),
- range_last.from(),
- range_last.to(),
- )
- };
- change_pos.extend_from_slice(&[start1, end1, start2, end2]);
+pub fn is_valid_tagname_char(ch: char) -> bool {
+ ch.is_alphanumeric() || ch == '_' || ch == '-' || ch == '.'
+}
+
+pub fn find_next_tag(text: RopeSlice, mut pos: usize, n: usize) -> Option<(usize, usize)> {
+ if pos >= text.len_chars() || n == 0 {
+ return None;
}
- Ok(change_pos)
+
+ let mut chars = text.chars_at(pos);
+ let mut possible_tag = String::new();
+
+ 'outer: loop {
+ // look forward, try to find something that looks like a closing tag e.g.