diff --git a/helix-core/src/surround.rs b/helix-core/src/surround.rs index b042b16ea..d52766d46 100644 --- a/helix-core/src/surround.rs +++ b/helix-core/src/surround.rs @@ -382,6 +382,45 @@ pub fn is_valid_tagname_char(ch: char) -> bool { // If they are the same, success. If they're different, continue looking forward until we find the same // Alternate between looking forward and backward +pub fn find_prev_tag( + text: RopeSlice, + mut pos: usize, + n: usize, +) -> Option<((usize, usize), String)> { + if pos == 0 || n == 0 { + return None; + } + + let mut chars = text.chars_at(pos); + let mut possible_tag = String::new(); + + 'outer: loop { + let prev_char = chars.prev()?; + pos -= 1; + + if prev_char == '>' { + let mut possible_tag_name = String::new(); + loop { + let current_char = chars.prev()?; + pos -= 1; + if current_char == '<' { + possible_tag.push_str( + &possible_tag_name + .chars() + .rev() + .take_while(|&ch| is_valid_tagname_char(ch)) + .collect::()[..], + ); + break 'outer; + } + possible_tag_name.push(current_char); + } + } + } + + Some(((pos + 1, pos + possible_tag.len()), possible_tag)) +} + pub fn find_next_tag( text: RopeSlice, mut pos: usize, @@ -472,7 +511,7 @@ mod test { let doc = Rope::from("hello"); assert_eq!( - find_next_tag(doc.slice(..), 7, 1).unwrap(), + find_prev_tag(doc.slice(..), 7, 1).unwrap(), ((1, 3), String::from("tag")) ); } @@ -482,7 +521,7 @@ mod test { let doc = Rope::from(" "); assert_eq!( - find_next_tag(doc.slice(..), 32, 1).unwrap(), + find_prev_tag(doc.slice(..), 32, 1).unwrap(), ((1, 11), String::from("Hello.World")) ); }