@@ -6,61 +6,114 @@ use core::{
66 str:: CharIndices ,
77} ;
88
9- fn consume_osc_end_exclusive ( it : & mut Peekable < CharIndices < ' _ > > , start : usize ) -> usize {
10- let mut end = start + 1 ;
11- let Some ( ( idx, ']' ) ) = it. next ( ) else {
12- return end;
13- } ;
14- end = idx + 1 ;
9+ struct EscAction {
10+ consume_next : bool ,
11+ end : bool ,
12+ }
1513
16- while let Some ( ( idx, c) ) = it. next ( ) {
17- end = idx + c. len_utf8 ( ) ;
18- match c {
19- '\u{07}' | '\u{9c}' => return end,
20- '\u{1b}' => {
21- if let Some ( ( next_idx, '\\' ) ) = it. peek ( ) {
22- end = * next_idx + 1 ;
23- it. next ( ) ;
24- return end;
25- }
14+ trait EscSequence {
15+ const START_CHAR : char ;
16+ fn on_char ( c : char ) -> EscAction ;
17+ fn on_escape ( next : Option < char > ) -> EscAction ;
18+ }
19+
20+ #[ derive( Clone , Copy , Debug ) ]
21+ struct OscSequence ;
22+
23+ impl EscSequence for OscSequence {
24+ const START_CHAR : char = ']' ;
25+
26+ fn on_char ( c : char ) -> EscAction {
27+ EscAction {
28+ consume_next : false ,
29+ end : c == '\u{07}' ,
30+ }
31+ }
32+
33+ fn on_escape ( next : Option < char > ) -> EscAction {
34+ if matches ! ( next, Some ( '\\' ) ) {
35+ EscAction {
36+ consume_next : true ,
37+ end : true ,
38+ }
39+ } else {
40+ EscAction {
41+ consume_next : false ,
42+ end : false ,
2643 }
27- _ => { }
2844 }
2945 }
46+ }
3047
31- end
48+ #[ derive( Clone , Copy , Debug ) ]
49+ struct DcsSequence ;
50+
51+ impl EscSequence for DcsSequence {
52+ const START_CHAR : char = 'P' ;
53+
54+ fn on_char ( _c : char ) -> EscAction {
55+ EscAction {
56+ consume_next : false ,
57+ end : false ,
58+ }
59+ }
60+
61+ fn on_escape ( next : Option < char > ) -> EscAction {
62+ match next {
63+ Some ( '\\' ) => EscAction {
64+ consume_next : true ,
65+ end : true ,
66+ } ,
67+ None => EscAction {
68+ consume_next : false ,
69+ end : true ,
70+ } ,
71+ Some ( '\u{1b}' ) => EscAction {
72+ consume_next : true ,
73+ end : false ,
74+ } ,
75+ _ => EscAction {
76+ consume_next : false ,
77+ end : false ,
78+ } ,
79+ }
80+ }
3281}
3382
34- fn consume_dcs_end_exclusive ( it : & mut Peekable < CharIndices < ' _ > > , start : usize ) -> usize {
83+ fn consume_end_exclusive < S : EscSequence > (
84+ it : & mut Peekable < CharIndices < ' _ > > ,
85+ start : usize ,
86+ ) -> usize {
3587 let mut end = start + 1 ;
36- let Some ( ( idx, 'P' ) ) = it. next ( ) else {
88+ let Some ( ( idx, start_char ) ) = it. next ( ) else {
3789 return end;
3890 } ;
91+ if start_char != S :: START_CHAR {
92+ return end;
93+ }
3994 end = idx + 1 ;
4095
4196 while let Some ( ( idx, c) ) = it. next ( ) {
4297 end = idx + c. len_utf8 ( ) ;
4398 match c {
4499 '\u{9c}' => return end,
45100 '\u{1b}' => {
46- let Some ( ( next_idx, next) ) = it. peek ( ) else {
47- return end;
48- } ;
49- match next {
50- '\u{1b}' => {
51- end = * next_idx + 1 ;
52- it. next ( ) ;
53- }
54- '\\' => {
101+ let action = S :: on_escape ( it. peek ( ) . map ( |( _, next) | * next) ) ;
102+ if action. consume_next {
103+ if let Some ( ( next_idx, _) ) = it. peek ( ) {
55104 end = * next_idx + 1 ;
56105 it. next ( ) ;
57- return end;
58106 }
59- _ => { }
107+ }
108+ if action. end {
109+ return end;
60110 }
61111 }
62112 _ => { }
63113 }
114+ if S :: on_char ( c) . end {
115+ return end;
116+ }
64117 }
65118
66119 end
@@ -231,8 +284,12 @@ fn find_ansi_code_exclusive(it: &mut Peekable<CharIndices>) -> Option<(usize, us
231284 '\u{1b}' => {
232285 it. next ( ) ;
233286 match it. peek ( ) {
234- Some ( ( _, ']' ) ) => return Some ( ( start, consume_osc_end_exclusive ( it, start) ) ) ,
235- Some ( ( _, 'P' ) ) => return Some ( ( start, consume_dcs_end_exclusive ( it, start) ) ) ,
287+ Some ( ( _, OscSequence :: START_CHAR ) ) => {
288+ return Some ( ( start, consume_end_exclusive :: < OscSequence > ( it, start) ) )
289+ }
290+ Some ( ( _, DcsSequence :: START_CHAR ) ) => {
291+ return Some ( ( start, consume_end_exclusive :: < DcsSequence > ( it, start) ) )
292+ }
236293 _ => {
237294 if let Some ( end) = find_dfa_end_exclusive_after_entry ( it) {
238295 return Some ( ( start, end) ) ;
0 commit comments