mirror of
https://github.com/helix-editor/helix.git
synced 2025-01-19 05:27:07 +04:00
Change test mark from ^@ to #[|]#
This commit is contained in:
parent
8350ee9a0e
commit
45b76db506
@ -1255,15 +1255,24 @@ fn test_behaviour_when_moving_to_end_of_next_long_words() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_prev_paragraph_single() {
|
||||
let tests = [
|
||||
("^@", "^@"),
|
||||
("^s@tart at\nfirst char\n", "@s^tart at\nfirst char\n"),
|
||||
("start at\nlast char^\n@", "@start at\nlast char\n^"),
|
||||
("goto\nfirst\n\n^p@aragraph", "@goto\nfirst\n\n^paragraph"),
|
||||
("goto\nfirst\n^\n@paragraph", "@goto\nfirst\n\n^paragraph"),
|
||||
("goto\nsecond\n\np^a@ragraph", "goto\nsecond\n\n@pa^ragraph"),
|
||||
("#[|]#", "#[|]#"),
|
||||
("#[s|]#tart at\nfirst char\n", "#[|s]#tart at\nfirst char\n"),
|
||||
("start at\nlast char#[\n|]#", "#[|start at\nlast char\n]#"),
|
||||
(
|
||||
"here\n\nhave\nmultiple\nparagraph\n\n\n\n\n^@",
|
||||
"here\n\n@have\nmultiple\nparagraph\n\n\n\n\n^",
|
||||
"goto\nfirst\n\n#[p|]#aragraph",
|
||||
"#[|goto\nfirst\n\n]#paragraph",
|
||||
),
|
||||
(
|
||||
"goto\nfirst\n#[\n|]#paragraph",
|
||||
"#[|goto\nfirst\n\n]#paragraph",
|
||||
),
|
||||
(
|
||||
"goto\nsecond\n\np#[a|]#ragraph",
|
||||
"goto\nsecond\n\n#[|pa]#ragraph",
|
||||
),
|
||||
(
|
||||
"here\n\nhave\nmultiple\nparagraph\n\n\n\n\n#[|]#",
|
||||
"here\n\n#[|have\nmultiple\nparagraph\n\n\n\n\n]#",
|
||||
),
|
||||
];
|
||||
|
||||
@ -1280,8 +1289,14 @@ fn test_behaviour_when_moving_to_prev_paragraph_single() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_prev_paragraph_double() {
|
||||
let tests = [
|
||||
("on^e@\n\ntwo\n\nthree\n\n", "@one^\n\ntwo\n\nthree\n\n"),
|
||||
("one\n\ntwo\n\nth^r@ee\n\n", "one\n\n@two\n\nthr^ee\n\n"),
|
||||
(
|
||||
"on#[e|]#\n\ntwo\n\nthree\n\n",
|
||||
"#[|one]#\n\ntwo\n\nthree\n\n",
|
||||
),
|
||||
(
|
||||
"one\n\ntwo\n\nth#[r|]#ee\n\n",
|
||||
"one\n\n#[|two\n\nthr]#ee\n\n",
|
||||
),
|
||||
];
|
||||
|
||||
for (before, expected) in tests {
|
||||
@ -1297,8 +1312,14 @@ fn test_behaviour_when_moving_to_prev_paragraph_double() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_prev_paragraph_extend() {
|
||||
let tests = [
|
||||
("one\n\n@two\n\n^three\n\n", "@one\n\ntwo\n\n^three\n\n"),
|
||||
("@one\n\ntwo\n\n^three\n\n", "@one\n\ntwo\n\n^three\n\n"),
|
||||
(
|
||||
"one\n\n#[|two\n\n]#three\n\n",
|
||||
"#[|one\n\ntwo\n\n]#three\n\n",
|
||||
),
|
||||
(
|
||||
"#[|one\n\ntwo\n\n]#three\n\n",
|
||||
"#[|one\n\ntwo\n\n]#three\n\n",
|
||||
),
|
||||
];
|
||||
|
||||
for (before, expected) in tests {
|
||||
@ -1314,24 +1335,24 @@ fn test_behaviour_when_moving_to_prev_paragraph_extend() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_next_paragraph_single() {
|
||||
let tests = [
|
||||
("^@", "^@"),
|
||||
("^s@tart at\nfirst char\n", "^start at\nfirst char\n@"),
|
||||
("start at\nlast char^\n@", "start at\nlast char^\n@"),
|
||||
("#[|]#", "#[|]#"),
|
||||
("#[s|]#tart at\nfirst char\n", "#[start at\nfirst char\n|]#"),
|
||||
("start at\nlast char#[\n|]#", "start at\nlast char#[\n|]#"),
|
||||
(
|
||||
"a\nb\n\n^g@oto\nthird\n\nparagraph",
|
||||
"a\nb\n\n^goto\nthird\n\n@paragraph",
|
||||
"a\nb\n\n#[g|]#oto\nthird\n\nparagraph",
|
||||
"a\nb\n\n#[goto\nthird\n\n|]#paragraph",
|
||||
),
|
||||
(
|
||||
"a\nb\n^\n@goto\nthird\n\nparagraph",
|
||||
"a\nb\n\n^goto\nthird\n\n@paragraph",
|
||||
"a\nb\n#[\n|]#goto\nthird\n\nparagraph",
|
||||
"a\nb\n\n#[goto\nthird\n\n|]#paragraph",
|
||||
),
|
||||
(
|
||||
"a\nb^\n@\ngoto\nsecond\n\nparagraph",
|
||||
"a\nb^\n\n@goto\nsecond\n\nparagraph",
|
||||
"a\nb#[\n|]#\ngoto\nsecond\n\nparagraph",
|
||||
"a\nb#[\n\n|]#goto\nsecond\n\nparagraph",
|
||||
),
|
||||
(
|
||||
"here\n\nhave\n^m@ultiple\nparagraph\n\n\n\n\n",
|
||||
"here\n\nhave\n^multiple\nparagraph\n\n\n\n\n@",
|
||||
"here\n\nhave\n#[m|]#ultiple\nparagraph\n\n\n\n\n",
|
||||
"here\n\nhave\n#[multiple\nparagraph\n\n\n\n\n|]#",
|
||||
),
|
||||
];
|
||||
|
||||
@ -1348,8 +1369,14 @@ fn test_behaviour_when_moving_to_next_paragraph_single() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_next_paragraph_double() {
|
||||
let tests = [
|
||||
("one\n\ntwo\n\nth^r@ee\n\n", "one\n\ntwo\n\nth^ree\n\n@"),
|
||||
("on^e@\n\ntwo\n\nthree\n\n", "on^e\n\ntwo\n\n@three\n\n"),
|
||||
(
|
||||
"one\n\ntwo\n\nth#[r|]#ee\n\n",
|
||||
"one\n\ntwo\n\nth#[ree\n\n|]#",
|
||||
),
|
||||
(
|
||||
"on#[e|]#\n\ntwo\n\nthree\n\n",
|
||||
"on#[e\n\ntwo\n\n|]#three\n\n",
|
||||
),
|
||||
];
|
||||
|
||||
for (before, expected) in tests {
|
||||
@ -1365,8 +1392,14 @@ fn test_behaviour_when_moving_to_next_paragraph_double() {
|
||||
#[test]
|
||||
fn test_behaviour_when_moving_to_next_paragraph_extend() {
|
||||
let tests = [
|
||||
("one\n\n^two\n\n@three\n\n", "one\n\n^two\n\nthree\n\n@"),
|
||||
("one\n\n^two\n\nthree\n\n@", "one\n\n^two\n\nthree\n\n@"),
|
||||
(
|
||||
"one\n\n#[two\n\n|]#three\n\n",
|
||||
"one\n\n#[two\n\nthree\n\n|]#",
|
||||
),
|
||||
(
|
||||
"one\n\n#[two\n\nthree\n\n|]#",
|
||||
"one\n\n#[two\n\nthree\n\n|]#",
|
||||
),
|
||||
];
|
||||
|
||||
for (before, expected) in tests {
|
||||
|
@ -5,8 +5,10 @@
|
||||
|
||||
/// Convert annotated test string to test string and selection.
|
||||
///
|
||||
/// `^` for `anchor` and `|` for head (`@` for primary), both must appear
|
||||
/// or otherwise it will panic.
|
||||
/// `#[|` for primary selection with head before anchor followed by `]#`.
|
||||
/// `#(|` for secondary selection with head before anchor followed by `)#`.
|
||||
/// `#[` for primary selection with head after anchor followed by `|]#`.
|
||||
/// `#(` for secondary selection with head after anchor followed by `|)#`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -15,7 +17,7 @@
|
||||
/// use smallvec::smallvec;
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// print("^a@b|c^"),
|
||||
/// print("#[a|]#b#(|c)#"),
|
||||
/// ("abc".to_owned(), Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0))
|
||||
/// );
|
||||
/// ```
|
||||
@ -26,56 +28,101 @@
|
||||
/// Panics when missing head or anchor.
|
||||
/// Panics when head come after head or anchor come after anchor.
|
||||
pub fn print(s: &str) -> (String, Selection) {
|
||||
let mut anchor = None;
|
||||
let mut head = None;
|
||||
let mut primary = None;
|
||||
let mut ranges = SmallVec::new();
|
||||
let mut i = 0;
|
||||
let s = s
|
||||
.chars()
|
||||
.filter(|c| {
|
||||
match c {
|
||||
'^' if anchor != None => panic!("anchor without head {s:?}"),
|
||||
'^' if head == None => anchor = Some(i),
|
||||
'^' => ranges.push(Range::new(i, head.take().unwrap())),
|
||||
'|' if head != None => panic!("head without anchor {s:?}"),
|
||||
'|' if anchor == None => head = Some(i),
|
||||
'|' => ranges.push(Range::new(anchor.take().unwrap(), i)),
|
||||
'@' if primary != None => panic!("head (primary) already appeared {s:?}"),
|
||||
'@' if head != None => panic!("head (primary) without anchor {s:?}"),
|
||||
'@' if anchor == None => {
|
||||
primary = Some(ranges.len());
|
||||
head = Some(i);
|
||||
let mut iter = s.chars().peekable();
|
||||
let mut left = String::with_capacity(s.len());
|
||||
'outer: while let Some(c) = iter.next() {
|
||||
let start = left.len();
|
||||
if c == '#' {
|
||||
if iter.next_if_eq(&'[').is_some() {
|
||||
if primary.is_some() {
|
||||
panic!("primary `#[` already appeared {left:?} {s:?}");
|
||||
}
|
||||
'@' => {
|
||||
primary = Some(ranges.len());
|
||||
ranges.push(Range::new(anchor.take().unwrap(), i));
|
||||
if iter.next_if_eq(&'|').is_some() {
|
||||
while let Some(c) = iter.next() {
|
||||
if c == ']' && iter.next_if_eq(&'#').is_some() {
|
||||
primary = Some(ranges.len());
|
||||
ranges.push(Range::new(left.len(), start));
|
||||
continue 'outer;
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
}
|
||||
panic!("missing primary end `]#` {left:?} {s:?}");
|
||||
} else {
|
||||
while let Some(c) = iter.next() {
|
||||
if c == '|' {
|
||||
if let Some(cc) = iter.next_if_eq(&']') {
|
||||
if iter.next_if_eq(&'#').is_some() {
|
||||
primary = Some(ranges.len());
|
||||
ranges.push(Range::new(start, left.len()));
|
||||
continue 'outer;
|
||||
} else {
|
||||
left.push(c);
|
||||
left.push(cc);
|
||||
}
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
}
|
||||
panic!("missing primary end `|]#` {left:?} {s:?}");
|
||||
}
|
||||
_ => {
|
||||
i += 1;
|
||||
return true;
|
||||
} else if iter.next_if_eq(&'(').is_some() {
|
||||
if iter.next_if_eq(&'|').is_some() {
|
||||
while let Some(c) = iter.next() {
|
||||
if c == ')' && iter.next_if_eq(&'#').is_some() {
|
||||
ranges.push(Range::new(left.len(), start));
|
||||
continue 'outer;
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
}
|
||||
panic!("missing end `)#` {left:?} {s:?}");
|
||||
} else {
|
||||
while let Some(c) = iter.next() {
|
||||
if c == '|' {
|
||||
if let Some(cc) = iter.next_if_eq(&')') {
|
||||
if iter.next_if_eq(&'#').is_some() {
|
||||
ranges.push(Range::new(start, left.len()));
|
||||
continue 'outer;
|
||||
} else {
|
||||
left.push(c);
|
||||
left.push(cc);
|
||||
}
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
}
|
||||
panic!("missing end `|)#` {left:?} {s:?}");
|
||||
}
|
||||
};
|
||||
false
|
||||
})
|
||||
.collect();
|
||||
if head.is_some() {
|
||||
panic!("missing anchor (|) {s:?}");
|
||||
}
|
||||
if anchor.is_some() {
|
||||
panic!("missing head (^) {s:?}");
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
} else {
|
||||
left.push(c);
|
||||
}
|
||||
}
|
||||
let primary = match primary {
|
||||
Some(i) => i,
|
||||
None => panic!("missing primary (@) {s:?}"),
|
||||
None => panic!("missing primary `#[|]#` {s:?}"),
|
||||
};
|
||||
let selection = Selection::new(ranges, primary);
|
||||
(s, selection)
|
||||
(left, selection)
|
||||
}
|
||||
|
||||
/// Convert test string and selection to annotated test string.
|
||||
///
|
||||
/// `^` for `anchor` and `|` for head (`@` for primary).
|
||||
/// `#[|` for primary selection with head before anchor followed by `]#`.
|
||||
/// `#(|` for secondary selection with head before anchor followed by `)#`.
|
||||
/// `#[` for primary selection with head after anchor followed by `|]#`.
|
||||
/// `#(` for secondary selection with head after anchor followed by `|)#`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@ -85,28 +132,30 @@ pub fn print(s: &str) -> (String, Selection) {
|
||||
///
|
||||
/// assert_eq!(
|
||||
/// plain("abc", Selection::new(smallvec![Range::new(0, 1), Range::new(3, 2)], 0)),
|
||||
/// "^a@b|c^".to_owned()
|
||||
/// "#[a|]#b#(|c)#".to_owned()
|
||||
/// );
|
||||
/// ```
|
||||
pub fn plain(s: &str, selection: Selection) -> String {
|
||||
let primary = selection.primary_index();
|
||||
let mut out = String::with_capacity(s.len() + 2 * selection.len());
|
||||
let mut out = String::with_capacity(s.len() + 5 * selection.len());
|
||||
out.push_str(s);
|
||||
let mut insertion: Vec<_> = selection
|
||||
.iter()
|
||||
.enumerate()
|
||||
.flat_map(|(i, range)| {
|
||||
[
|
||||
// sort like this before reversed so anchor < head later
|
||||
(range.head, if i == primary { '@' } else { '|' }),
|
||||
(range.anchor, '^'),
|
||||
]
|
||||
// sort like this before reversed so anchor < head later
|
||||
match (range.anchor < range.head, i == primary) {
|
||||
(true, true) => [(range.anchor, "#["), (range.head, "|]#")],
|
||||
(true, false) => [(range.anchor, "#("), (range.head, "|)#")],
|
||||
(false, true) => [(range.anchor, "]#"), (range.head, "#[|")],
|
||||
(false, false) => [(range.anchor, ")#"), (range.head, "#(|")],
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
// insert in reverse order
|
||||
insertion.sort_unstable_by_key(|k| Reverse(k.0));
|
||||
for (i, c) in insertion {
|
||||
out.insert(i, c);
|
||||
for (i, s) in insertion {
|
||||
out.insert_str(i, s);
|
||||
}
|
||||
out
|
||||
}
|
||||
|
@ -357,18 +357,21 @@ fn test_textobject_word() {
|
||||
#[test]
|
||||
fn test_textobject_paragraph_inside_single() {
|
||||
let tests = [
|
||||
("^@", "^@"),
|
||||
("firs^t@\n\nparagraph\n\n", "^first\n@\nparagraph\n\n"),
|
||||
("second\n\npa^r@agraph\n\n", "second\n\n^paragraph\n@\n"),
|
||||
("^f@irst char\n\n", "^first char\n@\n"),
|
||||
("last char\n^\n@", "last char\n\n^@"),
|
||||
("#[|]#", "#[|]#"),
|
||||
("firs#[t|]#\n\nparagraph\n\n", "#[first\n|]#\nparagraph\n\n"),
|
||||
(
|
||||
"empty to line\n^\n@paragraph boundary\n\n",
|
||||
"empty to line\n\n^paragraph boundary\n@\n",
|
||||
"second\n\npa#[r|]#agraph\n\n",
|
||||
"second\n\n#[paragraph\n|]#\n",
|
||||
),
|
||||
("#[f|]#irst char\n\n", "#[first char\n|]#\n"),
|
||||
("last char\n#[\n|]#", "last char\n\n#[|]#"),
|
||||
(
|
||||
"empty to line\n#[\n|]#paragraph boundary\n\n",
|
||||
"empty to line\n\n#[paragraph boundary\n|]#\n",
|
||||
),
|
||||
(
|
||||
"line to empty\n\n^p@aragraph boundary\n\n",
|
||||
"line to empty\n\n^paragraph boundary\n@\n",
|
||||
"line to empty\n\n#[p|]#aragraph boundary\n\n",
|
||||
"line to empty\n\n#[paragraph boundary\n|]#\n",
|
||||
),
|
||||
];
|
||||
|
||||
@ -386,12 +389,12 @@ fn test_textobject_paragraph_inside_single() {
|
||||
fn test_textobject_paragraph_inside_double() {
|
||||
let tests = [
|
||||
(
|
||||
"last two\n\n^p@aragraph\n\nwithout whitespaces\n\n",
|
||||
"last two\n\n^paragraph\n\nwithout whitespaces\n@\n",
|
||||
"last two\n\n#[p|]#aragraph\n\nwithout whitespaces\n\n",
|
||||
"last two\n\n#[paragraph\n\nwithout whitespaces\n|]#\n",
|
||||
),
|
||||
(
|
||||
"last two\n^\n@paragraph\n\nwithout whitespaces\n\n",
|
||||
"last two\n\n^paragraph\n\nwithout whitespaces\n@\n",
|
||||
"last two\n#[\n|]#paragraph\n\nwithout whitespaces\n\n",
|
||||
"last two\n\n#[paragraph\n\nwithout whitespaces\n|]#\n",
|
||||
),
|
||||
];
|
||||
|
||||
@ -408,18 +411,21 @@ fn test_textobject_paragraph_inside_double() {
|
||||
#[test]
|
||||
fn test_textobject_paragraph_around_single() {
|
||||
let tests = [
|
||||
("^@", "^@"),
|
||||
("firs^t@\n\nparagraph\n\n", "^first\n\n@paragraph\n\n"),
|
||||
("second\n\npa^r@agraph\n\n", "second\n\n^paragraph\n\n@"),
|
||||
("^f@irst char\n\n", "^first char\n\n@"),
|
||||
("last char\n^\n@", "last char\n\n^@"),
|
||||
("#[|]#", "#[|]#"),
|
||||
("firs#[t|]#\n\nparagraph\n\n", "#[first\n\n|]#paragraph\n\n"),
|
||||
(
|
||||
"empty to line\n^\n@paragraph boundary\n\n",
|
||||
"empty to line\n\n^paragraph boundary\n\n@",
|
||||
"second\n\npa#[r|]#agraph\n\n",
|
||||
"second\n\n#[paragraph\n\n|]#",
|
||||
),
|
||||
("#[f|]#irst char\n\n", "#[first char\n\n|]#"),
|
||||
("last char\n#[\n|]#", "last char\n\n#[|]#"),
|
||||
(
|
||||
"empty to line\n#[\n|]#paragraph boundary\n\n",
|
||||
"empty to line\n\n#[paragraph boundary\n\n|]#",
|
||||
),
|
||||
(
|
||||
"line to empty\n\n^p@aragraph boundary\n\n",
|
||||
"line to empty\n\n^paragraph boundary\n\n@",
|
||||
"line to empty\n\n#[p|]#aragraph boundary\n\n",
|
||||
"line to empty\n\n#[paragraph boundary\n\n|]#",
|
||||
),
|
||||
];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user