Skip to content

Commit

Permalink
Update surround commands to work with gap indexing.
Browse files Browse the repository at this point in the history
  • Loading branch information
cessen committed Jul 8, 2021
1 parent 753f7f3 commit b4c59b4
Show file tree
Hide file tree
Showing 6 changed files with 234 additions and 239 deletions.
6 changes: 3 additions & 3 deletions helix-core/src/movement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub fn move_horizontally(
};

// Compute the final new range.
range.put(slice, behaviour == Extend, new_pos)
range.put(slice, new_pos, behaviour == Extend)
}

pub fn move_vertically(
Expand Down Expand Up @@ -106,7 +106,7 @@ pub fn move_vertically(
new_pos
};

let mut new_range = range.put(slice, true, new_head);
let mut new_range = range.put(slice, new_head, true);
new_range.horiz = Some(horiz);
new_range
}
Expand Down Expand Up @@ -427,7 +427,7 @@ mod test {
#[test]
fn vertical_moves_in_single_column() {
let text = Rope::from(MULTILINE_SAMPLE);
let slice = dbg!(&text).slice(..);
let slice = text.slice(..);
let position = pos_at_coords(slice, (0, 0).into());
let mut range = Range::point(position);
let moves_and_expected_coordinates = IntoIter::new([
Expand Down
12 changes: 7 additions & 5 deletions helix-core/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ pub fn find_nth_next(
n: usize,
inclusive: bool,
) -> Option<usize> {
if pos >= text.len_chars() {
if pos >= text.len_chars() || n == 0 {
return None;
}

// start searching right after pos
let mut chars = text.chars_at(pos + 1);
let mut chars = text.chars_at(pos);

for _ in 0..n {
loop {
Expand Down Expand Up @@ -40,14 +39,17 @@ pub fn find_nth_prev(
n: usize,
inclusive: bool,
) -> Option<usize> {
// start searching right before pos
if pos == 0 || n == 0 {
return None;
}

let mut chars = text.chars_at(pos);

for _ in 0..n {
loop {
let c = chars.prev()?;

pos = pos.saturating_sub(1);
pos -= 1;

if c == ch {
break;
Expand Down
2 changes: 1 addition & 1 deletion helix-core/src/selection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ impl Range {
/// grapheme-aligned.
#[must_use]
#[inline]
pub fn put(self, text: RopeSlice, extend: bool, char_idx: usize) -> Range {
pub fn put(self, text: RopeSlice, char_idx: usize, extend: bool) -> Range {
let anchor = if !extend {
char_idx
} else if self.head >= self.anchor && char_idx < self.anchor {
Expand Down
76 changes: 45 additions & 31 deletions helix-core/src/surround.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::graphemes::next_grapheme_boundary;
use crate::{search, Selection};
use ropey::RopeSlice;

Expand Down Expand Up @@ -40,23 +41,35 @@ pub fn find_nth_pairs_pos(
) -> Option<(usize, usize)> {
let (open, close) = get_pair(ch);

let (open_pos, close_pos) = if open == close {
let prev = search::find_nth_prev(text, open, pos, n, true);
let next = search::find_nth_next(text, close, pos, n, true);
if text.char(pos) == open {
// cursor is *on* a pair
next.map(|n| (pos, n)).or_else(|| prev.map(|p| (p, pos)))?
if text.len_chars() < 2 || pos >= text.len_chars() {
return None;
}

if open == close {
if Some(open) == text.get_char(pos) {
// Special case: cursor is directly on a matching char.
match pos {
0 => Some((pos, search::find_nth_next(text, close, pos + 1, n, true)?)),
_ if (pos + 1) == text.len_chars() => Some((
search::find_nth_prev(text, open, pos, n, true)?,
text.len_chars(),
)),
// We return no match because there's no way to know which
// side of the char we should be searching on.
_ => None,
}
} else {
(prev?, next?)
Some((
search::find_nth_prev(text, open, pos, n, true)?,
search::find_nth_next(text, close, pos, n, true)?,
))
}
} else {
(
Some((
find_nth_open_pair(text, open, close, pos, n)?,
find_nth_close_pair(text, open, close, pos, n)?,
)
};

Some((open_pos, close_pos))
next_grapheme_boundary(text, find_nth_close_pair(text, open, close, pos, n)?),
))
}
}

fn find_nth_open_pair(
Expand Down Expand Up @@ -173,12 +186,13 @@ mod test {
let slice = doc.slice(..);

// cursor on [t]ext
assert_eq!(find_nth_pairs_pos(slice, '(', 6, 1), Some((5, 10)));
assert_eq!(find_nth_pairs_pos(slice, ')', 6, 1), Some((5, 10)));
assert_eq!(find_nth_pairs_pos(slice, '(', 6, 1), Some((5, 11)));
assert_eq!(find_nth_pairs_pos(slice, ')', 6, 1), Some((5, 11)));
// cursor on so[m]e
assert_eq!(find_nth_pairs_pos(slice, '(', 2, 1), None);
// cursor on bracket itself
assert_eq!(find_nth_pairs_pos(slice, '(', 5, 1), Some((5, 10)));
assert_eq!(find_nth_pairs_pos(slice, '(', 5, 1), Some((5, 11)));
assert_eq!(find_nth_pairs_pos(slice, '(', 10, 1), Some((5, 11)));
}

#[test]
Expand All @@ -187,9 +201,9 @@ mod test {
let slice = doc.slice(..);

// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 2), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 3), Some((0, 27)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((10, 16)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 2), Some((4, 22)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 3), Some((0, 28)));
}

#[test]
Expand All @@ -198,14 +212,14 @@ mod test {
let slice = doc.slice(..);

// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 2), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 3), Some((0, 27)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 1), Some((10, 16)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 2), Some((4, 22)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 13, 3), Some((0, 28)));
// cursor on the quotes
assert_eq!(find_nth_pairs_pos(slice, '\'', 10, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 10, 1), None);
// this is the best we can do since opening and closing pairs are same
assert_eq!(find_nth_pairs_pos(slice, '\'', 0, 1), Some((0, 4)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 27, 1), Some((21, 27)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 0, 1), Some((0, 5)));
assert_eq!(find_nth_pairs_pos(slice, '\'', 27, 1), Some((21, 28)));
}

#[test]
Expand All @@ -214,8 +228,8 @@ mod test {
let slice = doc.slice(..);

// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 1), Some((5, 24)));
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 2), Some((0, 31)));
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 1), Some((5, 25)));
assert_eq!(find_nth_pairs_pos(slice, '(', 15, 2), Some((0, 32)));
}

#[test]
Expand All @@ -224,9 +238,9 @@ mod test {
let slice = doc.slice(..);

// cursor on go[o]d
assert_eq!(find_nth_pairs_pos(slice, '{', 13, 1), Some((10, 15)));
assert_eq!(find_nth_pairs_pos(slice, '[', 13, 1), Some((4, 21)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((0, 27)));
assert_eq!(find_nth_pairs_pos(slice, '{', 13, 1), Some((10, 16)));
assert_eq!(find_nth_pairs_pos(slice, '[', 13, 1), Some((4, 22)));
assert_eq!(find_nth_pairs_pos(slice, '(', 13, 1), Some((0, 28)));
}

#[test]
Expand All @@ -243,7 +257,7 @@ mod test {
get_surround_pos(slice, &selection, '(', 1)
.unwrap()
.as_slice(),
&[0, 5, 7, 13, 15, 23]
&[0, 6, 7, 14, 15, 24]
);
}

Expand Down
Loading

0 comments on commit b4c59b4

Please sign in to comment.