@@ -573,11 +573,17 @@ fn parse4<'a>(input: &'a str) -> OpResult {
573573 nom:: sequence:: terminated ( nom:: combinator:: map_res ( P :: recognize, P :: map) , tail)
574574 }
575575
576- fn opt_param < ' a , P : Params < ' a > , Any > (
576+ fn opt_param < ' a , P : Params < ' a > + Copy , Any > (
577577 tail : impl StrParser < ' a , Any > ,
578578 default : P ,
579579 ) -> impl StrParser < ' a , P > {
580- move |input| todo ! ( )
580+ nom:: sequence:: terminated (
581+ nom:: combinator:: map_res ( nom:: combinator:: opt ( P :: recognize) , move |opt| match opt {
582+ None => Ok ( default) ,
583+ Some ( o) => P :: map ( o) ,
584+ } ) ,
585+ tail,
586+ )
581587 }
582588
583589 use nom:: branch:: alt;
@@ -717,7 +723,7 @@ pub fn parse6(input: &str) -> Result<Op, String> {
717723 nom:: combinator:: success ( "" ) ,
718724 ) ) ;
719725 let fin = nom:: combinator:: recognize ( nom:: character:: streaming:: satisfy ( |ch| {
720- '\x40' < ch && ch < '\x7e'
726+ ( '\x40' ..= '\x7e' ) . contains ( & ch )
721727 } ) ) ;
722728
723729 let ( rest, ( ( params, intermediate) , fin) ) =
@@ -792,38 +798,110 @@ pub fn parse6(input: &str) -> Result<Op, String> {
792798}
793799
794800fn parse3 ( input : & str ) -> OpResult {
795- use self :: start_with_esc as esc;
796801 use nom:: branch:: alt;
797802 use nom:: character:: streaming:: char as ch;
798- use nom:: combinator:: map;
803+ use nom:: combinator:: { cut, fail} ;
804+ use nom:: sequence:: terminated as term;
805+
806+ // can't use trait aliases in the return type, see: https://github.com/rust-lang/rust-analyzer/issues/13410
807+ fn esc < ' a , P : StrParser < ' a , O > , O > (
808+ parser : P ,
809+ ) -> impl nom:: Parser < & ' a str , O , nom:: error:: Error < & ' a str > > {
810+ nom:: sequence:: preceded ( ch ( '\x1b' ) , parser)
811+ }
812+
813+ // can't use trait aliases in the return type, see: https://github.com/rust-lang/rust-analyzer/issues/13410
814+ fn csi < ' a , P : StrParser < ' a , O > , O > (
815+ parser : P ,
816+ ) -> impl nom:: Parser < & ' a str , O , nom:: error:: Error < & ' a str > > {
817+ nom:: sequence:: preceded (
818+ alt ( (
819+ nom:: combinator:: recognize ( ch ( '\u{9b}' ) ) ,
820+ nom:: combinator:: recognize ( nom:: bytes:: streaming:: tag ( "\x1b [" ) ) ,
821+ ) ) ,
822+ parser,
823+ )
824+ }
825+
826+ trait Params < ' a > : Sized {
827+ type O ;
828+ type Err ;
829+ fn recognize ( input : & ' a str ) -> IResult < & ' a str , Self :: O > ;
830+ fn map ( o : Self :: O ) -> Result < Self , Self :: Err > ;
831+ }
832+ impl < ' a > Params < ' a > for ( usize , usize ) {
833+ type O = ( & ' a str , & ' a str ) ;
834+ type Err = ParseIntError ;
835+
836+ fn recognize ( input : & ' a str ) -> IResult < & ' a str , ( & ' a str , & ' a str ) > {
837+ nom:: sequence:: separated_pair (
838+ nom:: character:: streaming:: digit1,
839+ nom:: character:: streaming:: char ( ';' ) ,
840+ nom:: character:: streaming:: digit1,
841+ ) ( input)
842+ }
843+
844+ fn map ( ( a, b) : ( & ' a str , & ' a str ) ) -> Result < Self , ParseIntError > {
845+ Ok ( ( usize:: from_str ( a) ?, usize:: from_str ( b) ?) )
846+ }
847+ }
848+
849+ fn param < ' a , P : Params < ' a > > ( ) -> impl StrParser < ' a , P > {
850+ nom:: combinator:: map_res ( P :: recognize, P :: map)
851+ }
852+
853+ fn final_char < I , E : nom:: error:: ParseError < I > > ( i : I ) -> IResult < I , char , E >
854+ where
855+ I : nom:: Slice < nom:: lib:: std:: ops:: RangeFrom < usize > > + nom:: InputIter ,
856+ <I as nom:: InputIter >:: Item : nom:: AsChar ,
857+ {
858+ nom:: character:: streaming:: satisfy ( |ch| ( '\x40' ..='\x7e' ) . contains ( & ch) ) . parse ( i)
859+ }
860+
861+ fn non_final < I , E : nom:: error:: ParseError < I > > ( i : I ) -> IResult < I , I , E >
862+ where
863+ I : nom:: Slice < nom:: lib:: std:: ops:: RangeFrom < usize > >
864+ + nom:: Slice < nom:: lib:: std:: ops:: RangeTo < usize > >
865+ + nom:: InputIter
866+ + Clone
867+ + nom:: Offset
868+ + nom:: InputLength ,
869+ <I as nom:: InputIter >:: Item : nom:: AsChar ,
870+ {
871+ nom:: combinator:: recognize ( nom:: multi:: many0_count ( nom:: character:: streaming:: satisfy (
872+ |ch| !( '\x40' ..='\x7e' ) . contains ( & ch) ,
873+ ) ) )
874+ . parse ( i)
875+ }
876+
877+ fn bail < I , O , E : nom:: error:: ParseError < I > > ( i : I ) -> IResult < I , O , E > {
878+ cut ( fail) ( i)
879+ }
799880
800881 alt ( (
801882 alt ( (
802- esc ( map ( ch ( '7' ) , |_| Op :: SaveCursorPos ) ) ,
803- esc ( map ( ch ( '8' ) , |_| Op :: RestoreCursorPos ) ) ,
804- ) ) ,
805- esc ( nom:: sequence:: preceded (
806- ch ( '[' ) ,
807- map ( ch ( 'H' ) , |_| Op :: MoveCursorAbs { x : 0 , y : 0 } ) ,
808- ) ) ,
809- esc ( nom:: sequence:: preceded (
810- ch ( '[' ) ,
811- map ( dual_int_parameter_sequence :: < usize > ( 'H' ) , |( a, b) | {
812- Op :: MoveCursorAbs {
813- x : b. saturating_sub ( 1 ) ,
814- y : a. saturating_sub ( 1 ) ,
815- }
816- } ) ,
883+ esc ( ch ( '7' ) ) . map ( |_| Op :: SaveCursorPos ) ,
884+ esc ( ch ( '8' ) ) . map ( |_| Op :: RestoreCursorPos ) ,
817885 ) ) ,
818- esc ( nom :: sequence :: preceded (
819- ch ( '[' ) ,
820- map ( dual_int_parameter_sequence :: < usize > ( 'f ') , |( a, b) | {
886+ csi ( alt ( ( alt ( (
887+ alt ( ( ch ( 'H' ) , ch ( 'f' ) ) ) . map ( |_| Op :: MoveCursorAbs { x : 0 , y : 0 } ) ,
888+ term ( param :: < ( usize , usize ) > ( ) , alt ( ( ch ( 'H ') , ch ( 'f' ) ) ) ) . map ( |( a, b) | {
821889 Op :: MoveCursorAbs {
822890 x : b. saturating_sub ( 1 ) ,
823891 y : a. saturating_sub ( 1 ) ,
824892 }
825893 } ) ,
826- ) ) ,
894+ term ( non_final, alt ( ( ch ( 'H' ) , ch ( 'f' ) ) ) ) . and_then ( bail) ,
895+ ) ) , ) ) ) ,
896+ // unknown sequence
897+ nom:: combinator:: recognize ( nom:: sequence:: preceded (
898+ alt ( (
899+ esc ( nom:: combinator:: success ( ( ) ) ) ,
900+ csi ( nom:: combinator:: success ( ( ) ) ) ,
901+ ) ) ,
902+ term ( non_final, final_char) ,
903+ ) )
904+ . and_then ( bail) ,
827905 ) ) ( input)
828906}
829907
0 commit comments