@@ -360,7 +360,10 @@ impl GraphemeCursor {
360360match self . state {
361361GraphemeState :: Regional =>self . handle_regional ( chunk, chunk_start) ,
362362GraphemeState :: Emoji =>self . handle_emoji ( chunk, chunk_start) ,
363- _ =>panic ! ( "invalid state" )
363+ _ =>if self . cat_before . is_none ( ) &&self . offset == chunk. len ( ) + chunk_start{
364+ let ch = chunk. chars ( ) . rev ( ) . next ( ) . unwrap ( ) ;
365+ self . cat_before =Some ( gr:: grapheme_category ( ch) ) ;
366+ } ,
364367}
365368}
366369
@@ -406,6 +409,7 @@ impl GraphemeCursor {
406409return ;
407410}
408411self . pre_context_offset =Some ( chunk_start) ;
412+ self . state =GraphemeState :: Regional ;
409413}
410414
411415fn handle_emoji ( & mut self , chunk : & str , chunk_start : usize ) {
@@ -428,6 +432,7 @@ impl GraphemeCursor {
428432return ;
429433}
430434self . pre_context_offset =Some ( chunk_start) ;
435+ self . state =GraphemeState :: Emoji ;
431436}
432437
433438/// Determine whether the current cursor location is a grapheme cluster boundary.
@@ -664,6 +669,23 @@ impl GraphemeCursor {
664669}
665670}
666671
672+ fn test_grapheme_cursor_ris_precontext ( ) {
673+ let s ="\u{1f1fa} \u{1f1f8} \u{1f1fa} \u{1f1f8} \u{1f1fa} \u{1f1f8} " ;
674+ let mut c =GraphemeCursor :: new ( 8 , s. len ( ) , true ) ;
675+ assert_eq ! ( c. is_boundary( & s[ 4 ..] , 4 ) , Err ( GraphemeIncomplete :: PreContext ( 4 ) ) ) ;
676+ c. provide_context ( & s[ ..4 ] , 0 ) ;
677+ assert_eq ! ( c. is_boundary( & s[ 4 ..] , 4 ) , Ok ( true ) ) ;
678+ }
679+
680+ #[ test]
681+ fn test_grapheme_cursor_chunk_start_require_precontext ( ) {
682+ let s ="\r \n " ;
683+ let mut c =GraphemeCursor :: new ( 1 , s. len ( ) , true ) ;
684+ assert_eq ! ( c. is_boundary( & s[ 1 ..] , 1 ) , Err ( GraphemeIncomplete :: PreContext ( 1 ) ) ) ;
685+ c. provide_context ( & s[ ..1 ] , 0 ) ;
686+ assert_eq ! ( c. is_boundary( & s[ 1 ..] , 1 ) , Ok ( false ) ) ;
687+ }
688+
667689#[ test]
668690fn test_grapheme_cursor_prev_boundary ( ) {
669691let s ="abcd" ;