@@ -4,7 +4,7 @@ use ropey::iter::Chars;
44
55use crate :: {
66 char_idx_at_visual_offset,
7- chars:: { categorize_char, char_is_line_ending, CharCategory } ,
7+ chars:: { categorize_char, char_is_line_ending, CharCategory , WordChars } ,
88 doc_formatter:: TextFormat ,
99 graphemes:: {
1010 next_grapheme_boundary, nth_next_grapheme_boundary, nth_prev_grapheme_boundary,
@@ -165,20 +165,20 @@ pub fn move_vertically(
165165 new_range
166166}
167167
168- pub fn move_next_word_start ( slice : RopeSlice , range : Range , count : usize ) -> Range {
169- word_move ( slice, range, count, WordMotionTarget :: NextWordStart )
168+ pub fn move_next_word_start ( slice : RopeSlice , range : Range , count : usize , word_chars : & WordChars ) -> Range {
169+ word_move ( slice, range, count, WordMotionTarget :: NextWordStart ( word_chars ) )
170170}
171171
172- pub fn move_next_word_end ( slice : RopeSlice , range : Range , count : usize ) -> Range {
173- word_move ( slice, range, count, WordMotionTarget :: NextWordEnd )
172+ pub fn move_next_word_end ( slice : RopeSlice , range : Range , count : usize , word_chars : & WordChars ) -> Range {
173+ word_move ( slice, range, count, WordMotionTarget :: NextWordEnd ( word_chars ) )
174174}
175175
176- pub fn move_prev_word_start ( slice : RopeSlice , range : Range , count : usize ) -> Range {
177- word_move ( slice, range, count, WordMotionTarget :: PrevWordStart )
176+ pub fn move_prev_word_start ( slice : RopeSlice , range : Range , count : usize , word_chars : & WordChars ) -> Range {
177+ word_move ( slice, range, count, WordMotionTarget :: PrevWordStart ( word_chars ) )
178178}
179179
180- pub fn move_prev_word_end ( slice : RopeSlice , range : Range , count : usize ) -> Range {
181- word_move ( slice, range, count, WordMotionTarget :: PrevWordEnd )
180+ pub fn move_prev_word_end ( slice : RopeSlice , range : Range , count : usize , word_chars : & WordChars ) -> Range {
181+ word_move ( slice, range, count, WordMotionTarget :: PrevWordEnd ( word_chars ) )
182182}
183183
184184pub fn move_next_long_word_start ( slice : RopeSlice , range : Range , count : usize ) -> Range {
@@ -216,10 +216,10 @@ pub fn move_prev_sub_word_end(slice: RopeSlice, range: Range, count: usize) -> R
216216fn word_move ( slice : RopeSlice , range : Range , count : usize , target : WordMotionTarget ) -> Range {
217217 let is_prev = matches ! (
218218 target,
219- WordMotionTarget :: PrevWordStart
219+ WordMotionTarget :: PrevWordStart ( _ )
220220 | WordMotionTarget :: PrevLongWordStart
221221 | WordMotionTarget :: PrevSubWordStart
222- | WordMotionTarget :: PrevWordEnd
222+ | WordMotionTarget :: PrevWordEnd ( _ )
223223 | WordMotionTarget :: PrevLongWordEnd
224224 | WordMotionTarget :: PrevSubWordEnd
225225 ) ;
@@ -389,11 +389,11 @@ where
389389
390390/// Possible targets of a word motion
391391#[ derive( Copy , Clone , Debug ) ]
392- pub enum WordMotionTarget {
393- NextWordStart ,
394- NextWordEnd ,
395- PrevWordStart ,
396- PrevWordEnd ,
392+ pub enum WordMotionTarget < ' a > {
393+ NextWordStart ( & ' a WordChars ) ,
394+ NextWordEnd ( & ' a WordChars ) ,
395+ PrevWordStart ( & ' a WordChars ) ,
396+ PrevWordEnd ( & ' a WordChars ) ,
397397 // A "Long word" (also known as a WORD in Vim/Kakoune) is strictly
398398 // delimited by whitespace, and can consist of punctuation as well
399399 // as alphanumerics.
@@ -420,10 +420,10 @@ impl CharHelpers for Chars<'_> {
420420 fn range_to_target ( & mut self , target : WordMotionTarget , origin : Range ) -> Range {
421421 let is_prev = matches ! (
422422 target,
423- WordMotionTarget :: PrevWordStart
423+ WordMotionTarget :: PrevWordStart ( _ )
424424 | WordMotionTarget :: PrevLongWordStart
425425 | WordMotionTarget :: PrevSubWordStart
426- | WordMotionTarget :: PrevWordEnd
426+ | WordMotionTarget :: PrevWordEnd ( _ )
427427 | WordMotionTarget :: PrevLongWordEnd
428428 | WordMotionTarget :: PrevSubWordEnd
429429 ) ;
@@ -489,8 +489,8 @@ impl CharHelpers for Chars<'_> {
489489 }
490490}
491491
492- fn is_word_boundary ( a : char , b : char ) -> bool {
493- categorize_char ( a) != categorize_char ( b)
492+ fn is_word_boundary ( a : char , b : char , word_chars : & WordChars ) -> bool {
493+ word_chars . categorize ( a) != word_chars . categorize ( b)
494494}
495495
496496fn is_long_word_boundary ( a : char , b : char ) -> bool {
@@ -523,12 +523,12 @@ fn is_sub_word_boundary(a: char, b: char, dir: Direction) -> bool {
523523
524524fn reached_target ( target : WordMotionTarget , prev_ch : char , next_ch : char ) -> bool {
525525 match target {
526- WordMotionTarget :: NextWordStart | WordMotionTarget :: PrevWordEnd => {
527- is_word_boundary ( prev_ch, next_ch)
526+ WordMotionTarget :: NextWordStart ( word_chars ) | WordMotionTarget :: PrevWordEnd ( word_chars ) => {
527+ is_word_boundary ( prev_ch, next_ch, word_chars )
528528 && ( char_is_line_ending ( next_ch) || !next_ch. is_whitespace ( ) )
529529 }
530- WordMotionTarget :: NextWordEnd | WordMotionTarget :: PrevWordStart => {
531- is_word_boundary ( prev_ch, next_ch)
530+ WordMotionTarget :: NextWordEnd ( word_chars ) | WordMotionTarget :: PrevWordStart ( word_chars ) => {
531+ is_word_boundary ( prev_ch, next_ch, word_chars )
532532 && ( !prev_ch. is_whitespace ( ) || char_is_line_ending ( next_ch) )
533533 }
534534 WordMotionTarget :: NextLongWordStart | WordMotionTarget :: PrevLongWordEnd => {
@@ -979,19 +979,22 @@ mod test {
979979 #[ test]
980980 #[ should_panic]
981981 fn nonsensical_ranges_panic_on_forward_movement_attempt_in_debug_mode ( ) {
982- move_next_word_start ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 ) ;
982+ let word_chars = WordChars :: default ( ) ;
983+ move_next_word_start ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 , & word_chars) ;
983984 }
984985
985986 #[ test]
986987 #[ should_panic]
987988 fn nonsensical_ranges_panic_on_forward_to_end_movement_attempt_in_debug_mode ( ) {
988- move_next_word_end ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 ) ;
989+ let word_chars = WordChars :: default ( ) ;
990+ move_next_word_end ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 , & word_chars) ;
989991 }
990992
991993 #[ test]
992994 #[ should_panic]
993995 fn nonsensical_ranges_panic_on_backwards_movement_attempt_in_debug_mode ( ) {
994- move_prev_word_start ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 ) ;
996+ let word_chars = WordChars :: default ( ) ;
997+ move_prev_word_start ( Rope :: from ( "Sample" ) . slice ( ..) , Range :: point ( 99999999 ) , 1 , & word_chars) ;
995998 }
996999
9971000 #[ test]
@@ -1071,10 +1074,11 @@ mod test {
10711074 ( 1 , Range :: new( 0 , 0 ) , Range :: new( 0 , 6 ) ) ,
10721075 ] ) ,
10731076 ] ;
1077+ let word_chars = WordChars :: default ( ) ;
10741078
10751079 for ( sample, scenario) in tests {
10761080 for ( count, begin, expected_end) in scenario. into_iter ( ) {
1077- let range = move_next_word_start ( Rope :: from ( sample) . slice ( ..) , begin, count) ;
1081+ let range = move_next_word_start ( Rope :: from ( sample) . slice ( ..) , begin, count, & word_chars ) ;
10781082 assert_eq ! ( range, expected_end, "Case failed: [{}]" , sample) ;
10791083 }
10801084 }
@@ -1412,10 +1416,11 @@ mod test {
14121416 ( 1 , Range :: new( 0 , 6 ) , Range :: new( 6 , 0 ) ) ,
14131417 ] ) ,
14141418 ] ;
1419+ let word_chars = WordChars :: default ( ) ;
14151420
14161421 for ( sample, scenario) in tests {
14171422 for ( count, begin, expected_end) in scenario. into_iter ( ) {
1418- let range = move_prev_word_start ( Rope :: from ( sample) . slice ( ..) , begin, count) ;
1423+ let range = move_prev_word_start ( Rope :: from ( sample) . slice ( ..) , begin, count, & word_chars ) ;
14191424 assert_eq ! ( range, expected_end, "Case failed: [{}]" , sample) ;
14201425 }
14211426 }
@@ -1679,10 +1684,11 @@ mod test {
16791684 ( 1 , Range :: new( 0 , 0 ) , Range :: new( 0 , 5 ) ) ,
16801685 ] ) ,
16811686 ] ;
1687+ let word_chars = WordChars :: default ( ) ;
16821688
16831689 for ( sample, scenario) in tests {
16841690 for ( count, begin, expected_end) in scenario. into_iter ( ) {
1685- let range = move_next_word_end ( Rope :: from ( sample) . slice ( ..) , begin, count) ;
1691+ let range = move_next_word_end ( Rope :: from ( sample) . slice ( ..) , begin, count, & word_chars ) ;
16861692 assert_eq ! ( range, expected_end, "Case failed: [{}]" , sample) ;
16871693 }
16881694 }
@@ -1761,10 +1767,11 @@ mod test {
17611767 ( 1 , Range :: new( 0 , 10 ) , Range :: new( 10 , 4 ) ) ,
17621768 ] ) ,
17631769 ] ;
1770+ let word_chars = WordChars :: default ( ) ;
17641771
17651772 for ( sample, scenario) in tests {
17661773 for ( count, begin, expected_end) in scenario. into_iter ( ) {
1767- let range = move_prev_word_end ( Rope :: from ( sample) . slice ( ..) , begin, count) ;
1774+ let range = move_prev_word_end ( Rope :: from ( sample) . slice ( ..) , begin, count, & word_chars ) ;
17681775 assert_eq ! ( range, expected_end, "Case failed: [{}]" , sample) ;
17691776 }
17701777 }
0 commit comments