Fix parsing multiple selection ranges in TestState
use crate::movement::{SelRegion, Selection};
use lazy_static::lazy_static;
-use regex::{Captures, Regex};
+use regex::Regex;
#[derive(PartialEq)]
pub struct TestState {
@@ -19,12 +19,13 @@ impl Debug for TestState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut contents = self.contents.clone();
let mut inserted = 0;
+
+ // If we were to allow overlapping selections, this would not be correct.
for (id, region) in self.selection.regions().iter().enumerate() {
let marker = format!("<${id}>");
contents.insert_str(region.start() + inserted, &marker);
inserted += marker.len();
- }
- for (id, region) in self.selection.regions().iter().enumerate() {
+
if !region.is_caret() {
let marker = format!("</${id}>");
contents.insert_str(region.end() + inserted, &marker);
@@ -51,8 +52,7 @@ fn eq(&self, other: &TestState) -> bool {
impl TestState {
pub fn parse(initial: &str) -> Self {
lazy_static! {
- static ref START: Regex = Regex::new(r#"<\$(\d+)>"#).unwrap();
- static ref END: Regex = Regex::new(r#"</\$(\d+)>"#).unwrap();
+ static ref TAG: Regex = Regex::new(r#"<[/]?\$(\d+)>"#).unwrap();
}
let mut starts = HashMap::new();
@@ -62,8 +62,7 @@ pub fn parse(initial: &str) -> Self {
let mut contents = initial.to_string();
- let mut record_cursor_marker =
- |captures: Captures, map: &mut HashMap<usize, usize>| {
+ for captures in TAG.captures_iter(initial) {
let whole_match = captures.get(0).unwrap();
let id_match = captures.get(1).unwrap();
@@ -73,20 +72,19 @@ pub fn parse(initial: &str) -> Self {
let end = whole_match.end() - removed;
let marker_len = end - start;
- map.insert(cursor_id, start)
+ if whole_match.as_str().starts_with("</") {
+ ends.insert(cursor_id, start).map(|_| {
+ panic!("Duplicate selection end marker: {whole_match:?}")
+ });
+ } else {
+ starts
+ .insert(cursor_id, start)
.map(|_| panic!("Duplicate cursor marker: {whole_match:?}"));
+ }
unsafe { contents.as_mut_vec() }.drain(start..end);
removed += marker_len;
- };
-
- for start in START.captures_iter(initial) {
- record_cursor_marker(start, &mut starts);
- }
-
- for end in END.captures_iter(initial) {
- record_cursor_marker(end, &mut ends);
}
let mut selection = Selection::new();
