1
- import { Line , SerialMonitorOutput } from './serial-monitor-send-output' ;
1
+ import { Line , SerialMonitorOutput } from './serial-monitor-send-output' ;
2
+
3
+ function writeOverLine ( line : Line , insert : string , cursorPosition : number ) : [ number , number ] {
4
+ var lenBefore = line . message . length ;
5
+ line . message = line . message . substring ( 0 , cursorPosition ) + insert + line . message . substring ( cursorPosition + insert . length )
6
+ cursorPosition = cursorPosition + insert . length ;
7
+ line . lineLen = line . message . length ;
8
+ return [ line . lineLen - lenBefore , cursorPosition ] ;
9
+ }
10
+
11
+ const escapeSequenceGoHome = '\x1B[H' ;
12
+ const escapeSequenceClearScreen = '\x1B[2J' ;
2
13
3
14
export function messagesToLines (
4
15
messages : string [ ] ,
5
16
prevLines : Line [ ] = [ ] ,
6
17
charCount = 0 ,
7
- separator = '\n'
8
- ) : [ Line [ ] , number ] {
9
- const linesToAdd : Line [ ] = prevLines . length
10
- ? [ prevLines [ prevLines . length - 1 ] ]
11
- : [ { message : '' , lineLen : 0 } ] ;
12
- if ( ! ( Symbol . iterator in Object ( messages ) ) ) return [ prevLines , charCount ] ;
18
+ currentLineIndex : number | null ,
19
+ currentCursorPosition : number ,
20
+ separator = '\n' ,
21
+ ) : [ Line [ ] , number , number | null , number , string | null ] {
22
+ if ( ! prevLines . length ) {
23
+ prevLines = [ { message : '' , lineLen : 0 , timestamp : new Date ( ) } ] ;
24
+ }
25
+
26
+ currentLineIndex = currentLineIndex || 0 ;
13
27
14
- for ( const message of messages ) {
15
- const messageLen = message . length ;
16
- charCount += messageLen ;
17
- const lastLine = linesToAdd [ linesToAdd . length - 1 ] ;
28
+ let allMessages = messages . join ( '' ) ;
29
+ let overflow = null ;
18
30
19
- // if the previous messages ends with "separator" add a new line
20
- if ( lastLine . message . charAt ( lastLine . message . length - 1 ) === separator ) {
21
- linesToAdd . push ( {
22
- message,
23
- timestamp : new Date ( ) ,
24
- lineLen : messageLen ,
25
- } ) ;
26
- } else {
27
- // concatenate to the last line
28
- linesToAdd [ linesToAdd . length - 1 ] . message += message ;
29
- linesToAdd [ linesToAdd . length - 1 ] . lineLen += messageLen ;
30
- if ( ! linesToAdd [ linesToAdd . length - 1 ] . timestamp ) {
31
- linesToAdd [ linesToAdd . length - 1 ] . timestamp = new Date ( ) ;
31
+ if ( allMessages . indexOf ( escapeSequenceGoHome ) >= 0 ) {
32
+ const before = allMessages . substring ( 0 , allMessages . indexOf ( escapeSequenceGoHome ) ) ;
33
+ const after = allMessages . substring ( allMessages . indexOf ( escapeSequenceGoHome ) + escapeSequenceGoHome . length ) ;
34
+ const [ _lines , _charCount ] = messagesToLines ( [ before ] , prevLines , charCount , currentLineIndex , currentCursorPosition , separator ) ;
35
+ return messagesToLines ( [ after ] , _lines , _charCount , 0 , 0 , separator ) ;
36
+ } else if ( allMessages . indexOf ( escapeSequenceClearScreen ) >= 0 ) {
37
+ const after = allMessages . substring ( allMessages . lastIndexOf ( escapeSequenceClearScreen ) + escapeSequenceClearScreen . length ) ;
38
+ return messagesToLines ( [ after ] , [ ] , 0 , 0 , 0 , separator ) ;
39
+ } else if ( allMessages . lastIndexOf ( '\x1B' ) >= 0 ) {
40
+ overflow = allMessages . substring ( allMessages . lastIndexOf ( '\x1B' ) ) ;
41
+ const result = messagesToLines ( [ allMessages . substring ( 0 , allMessages . lastIndexOf ( '\x1B' ) ) ] , prevLines , charCount , currentLineIndex , currentCursorPosition , separator ) ;
42
+ result [ 4 ] = overflow ;
43
+ return result ;
44
+ }
45
+
46
+ const chunks = allMessages . split ( separator ) ;
47
+ for ( let i = 0 ; i < chunks . length ; i ++ ) {
48
+ const chunk = chunks [ i ] ;
49
+ if ( chunk !== '' ) {
50
+ if ( prevLines [ currentLineIndex ] . message [ currentCursorPosition - 1 ] === '\n' ) {
51
+ currentLineIndex ++ ;
52
+ currentCursorPosition = 0 ;
53
+ }
54
+ if ( currentLineIndex > prevLines . length - 1 ) {
55
+ prevLines . push ( { message : '' , lineLen : 0 , timestamp : new Date ( ) } ) ;
32
56
}
57
+ let [ _addedCharacters , _currentCursorPosition ] = writeOverLine ( prevLines [ currentLineIndex ] , chunk , currentCursorPosition )
58
+ charCount += _addedCharacters ;
59
+ currentCursorPosition = _currentCursorPosition ;
60
+ }
61
+
62
+ if ( i < chunks . length - 1 ) {
63
+ let [ _addedCharacters , _currentCursorPosition ] = writeOverLine ( prevLines [ currentLineIndex ] , separator , currentCursorPosition )
64
+ charCount += _addedCharacters ;
65
+ currentCursorPosition = _currentCursorPosition ;
33
66
}
34
67
}
35
68
36
- prevLines . splice ( prevLines . length - 1 , 1 , ...linesToAdd ) ;
37
- return [ prevLines , charCount ] ;
69
+ return [ prevLines , charCount , currentLineIndex , currentCursorPosition , overflow ]
38
70
}
39
71
40
72
export function truncateLines (
41
73
lines : Line [ ] ,
42
74
charCount : number ,
75
+ currentLineIndex : number | null ,
76
+ currentCursorPosition : number ,
43
77
maxCharacters : number = SerialMonitorOutput . MAX_CHARACTERS
44
- ) : [ Line [ ] , number ] {
78
+ ) : [ Line [ ] , number , number | null , number ] {
45
79
let charsToDelete = charCount - maxCharacters ;
46
80
let lineIndex = 0 ;
47
81
while ( charsToDelete > 0 || lineIndex > 0 ) {
@@ -65,5 +99,5 @@ export function truncateLines(
65
99
charsToDelete -= deletedCharsCount ;
66
100
lines [ 0 ] . message = newFirstLine ;
67
101
}
68
- return [ lines , charCount ] ;
102
+ return [ lines , charCount , currentLineIndex , currentCursorPosition ] ;
69
103
}
0 commit comments