Fix around-word text-object selection. (#546)

* Fix around-word text-object selection.

* Text object around-word: select to the left if no whitespace on the right.

Also only select around when there's whitespace at all.

* Make select-word-around select all white space on a side.

* Update commented-out test case.

* Fix unused import warning from rebase.
pull/553/head
Nathan Vegdahl 3 years ago committed by GitHub
parent 10c77cdc03
commit 953125d3f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,7 +1,7 @@
use ropey::RopeSlice; use ropey::RopeSlice;
use crate::chars::{categorize_char, CharCategory}; use crate::chars::{categorize_char, char_is_whitespace, CharCategory};
use crate::graphemes::{next_grapheme_boundary, prev_grapheme_boundary}; use crate::graphemes::next_grapheme_boundary;
use crate::movement::Direction; use crate::movement::Direction;
use crate::surround; use crate::surround;
use crate::Range; use crate::Range;
@ -73,19 +73,23 @@ pub fn textobject_word(
match textobject { match textobject {
TextObject::Inside => Range::new(word_start, word_end), TextObject::Inside => Range::new(word_start, word_end),
TextObject::Around => Range::new( TextObject::Around => {
match slice let whitespace_count_right = slice
.get_char(word_start.saturating_sub(1)) .chars_at(word_end)
.map(categorize_char) .take_while(|c| char_is_whitespace(*c))
{ .count();
None | Some(CharCategory::Eol) => word_start,
_ => prev_grapheme_boundary(slice, word_start), if whitespace_count_right > 0 {
}, Range::new(word_start, word_end + whitespace_count_right)
match slice.get_char(word_end).map(categorize_char) { } else {
None | Some(CharCategory::Eol) => word_end, let whitespace_count_left = {
_ => next_grapheme_boundary(slice, word_end), let mut iter = slice.chars_at(word_start);
}, iter.reverse();
), iter.take_while(|c| char_is_whitespace(*c)).count()
};
Range::new(word_start - whitespace_count_left, word_end)
}
}
} }
} }
@ -126,9 +130,9 @@ mod test {
(13, Inside, (10, 16)), (13, Inside, (10, 16)),
(10, Inside, (10, 16)), (10, Inside, (10, 16)),
(15, Inside, (10, 16)), (15, Inside, (10, 16)),
(13, Around, (9, 17)), (13, Around, (10, 17)),
(10, Around, (9, 17)), (10, Around, (10, 17)),
(15, Around, (9, 17)), (15, Around, (10, 17)),
], ],
), ),
( (
@ -167,9 +171,9 @@ mod test {
(13, Inside, (10, 16)), (13, Inside, (10, 16)),
(10, Inside, (10, 16)), (10, Inside, (10, 16)),
(15, Inside, (10, 16)), (15, Inside, (10, 16)),
(13, Around, (9, 17)), (13, Around, (10, 17)),
(10, Around, (9, 17)), (10, Around, (10, 17)),
(15, Around, (9, 17)), (15, Around, (10, 17)),
], ],
), ),
( (
@ -178,10 +182,9 @@ mod test {
(14, Inside, (14, 21)), (14, Inside, (14, 21)),
(20, Inside, (14, 21)), (20, Inside, (14, 21)),
(17, Inside, (14, 21)), (17, Inside, (14, 21)),
(14, Around, (13, 22)), (14, Around, (14, 21)),
// FIXME: edge case (20, Around, (14, 21)),
// (20, Around, (14, 20)), (17, Around, (14, 21)),
(17, Around, (13, 22)),
], ],
), ),
( (
@ -195,6 +198,14 @@ mod test {
(11, Around, (11, 11)), (11, Around, (11, 11)),
], ],
), ),
(
"cursor on word with extra whitespace",
vec![(11, Inside, (10, 14)), (11, Around, (10, 17))],
),
(
"cursor at end with extra whitespace",
vec![(28, Inside, (27, 37)), (28, Around, (24, 37))],
),
( (
"cursor at end of doc", "cursor at end of doc",
vec![(19, Inside, (17, 20)), (19, Around, (16, 20))], vec![(19, Inside, (17, 20)), (19, Around, (16, 20))],

Loading…
Cancel
Save