@@ -13,27 +13,63 @@ const create = (stream: Writable, {showCursor = false} = {}): LogUpdate => {
1313 let previousOutput = '' ;
1414 let hasHiddenCursor = false ;
1515
16+ function clear ( ) : void {
17+ stream . write ( ansiEscapes . eraseLines ( previousLineCount ) ) ;
18+ previousOutput = '' ;
19+ previousLineCount = 0 ;
20+ }
21+
1622 const render = ( str : string ) => {
1723 if ( ! showCursor && ! hasHiddenCursor ) {
1824 cliCursor . hide ( ) ;
1925 hasHiddenCursor = true ;
2026 }
2127
28+ if ( str === '' ) {
29+ clear ( ) ;
30+ return ;
31+ }
32+
2233 const output = str + '\n' ;
2334 if ( output === previousOutput ) {
2435 return ;
2536 }
2637
38+ const prevLines = previousOutput . split ( '\n' ) ;
39+ const newLines = output . split ( '\n' ) ;
40+ const newLinesCount = newLines . length ;
41+ let updateSequence = '' ;
42+
43+ // If new output is shorter than previous output, erase the extra lines.
44+ const numExtraOldLines = previousLineCount - newLinesCount ;
45+ if ( numExtraOldLines > 0 ) {
46+ // Note eraseLines() erases upwards.
47+ updateSequence += ansiEscapes . eraseLines ( numExtraOldLines ) ;
48+ }
49+
50+ // Move back up to the start of previous output.
51+ updateSequence +=
52+ ansiEscapes . cursorUp ( previousLineCount ) + ansiEscapes . cursorLeft ;
53+
54+ newLines . forEach ( ( newLine , index ) => {
55+ if ( newLine !== prevLines [ index ] ) {
56+ updateSequence += newLine + ansiEscapes . eraseEndLine ;
57+ }
58+
59+ if ( index < newLinesCount - 1 ) {
60+ // Note this could be more efficient if we used cursorDown() to move
61+ // multiple lines at once.
62+ updateSequence += ansiEscapes . cursorNextLine ;
63+ }
64+ } ) ;
65+
66+ stream . write ( updateSequence ) ;
67+
2768 previousOutput = output ;
28- stream . write ( ansiEscapes . eraseLines ( previousLineCount ) + output ) ;
29- previousLineCount = output . split ( '\n' ) . length ;
69+ previousLineCount = newLinesCount ;
3070 } ;
3171
32- render . clear = ( ) => {
33- stream . write ( ansiEscapes . eraseLines ( previousLineCount ) ) ;
34- previousOutput = '' ;
35- previousLineCount = 0 ;
36- } ;
72+ render . clear = clear ;
3773
3874 render . done = ( ) => {
3975 previousOutput = '' ;
0 commit comments