@@ -48,14 +48,14 @@ export class TerminalModel {
4848 }
4949
5050 write ( text ) {
51- this . buffer += text ;
51+ const buffer = this . buffer + text ;
5252 let lastReadIndex = 0 ;
5353
5454 let commandBuffer = null ;
5555 let currentText = '' ;
5656
57- for ( let i = 0 ; i < this . buffer . length ; i ++ ) {
58- const char = this . buffer [ i ] ;
57+ for ( let i = 0 ; i < buffer . length ; i ++ ) {
58+ const char = buffer [ i ] ;
5959
6060 if ( commandBuffer !== null ) {
6161 commandBuffer += char ;
@@ -114,7 +114,7 @@ export class TerminalModel {
114114 }
115115
116116 this . flushText ( currentText ) ;
117- this . buffer = this . buffer . substr ( lastReadIndex + 1 ) ;
117+ this . buffer = buffer . substr ( lastReadIndex + 1 ) ;
118118
119119 const changedLines = this . changedLines ;
120120 this . changedLines = [ ] ;
@@ -163,23 +163,87 @@ export class TerminalModel {
163163 this . addChangedLine ( this . currentLine ) ;
164164 }
165165
166- clearLineToLeft ( ) {
167- if ( this . currentPosition === 0 ) {
166+ clearLineToLeft ( position ) {
167+ if ( position === 0 ) {
168168 return ;
169169 }
170170
171171 const line = this . getLine ( this . currentLine ) ;
172- if ( line . length <= this . currentPosition ) {
172+ if ( line . length <= position ) {
173173 this . lines [ this . currentLine ] = '' ;
174174 this . addChangedLine ( this . currentLine ) ;
175175 return ;
176176 }
177177
178- const spaces = ' ' . repeat ( this . currentPosition ) ;
179- this . lines [ this . currentLine ] = spaces + line . substring ( this . currentPosition ) ;
178+ const spaces = ' ' . repeat ( position ) ;
179+ this . lines [ this . currentLine ] = spaces + line . substring ( position ) ;
180180 this . addChangedLine ( this . currentLine ) ;
181181 }
182182
183+ deleteBottomLines ( startLine ) {
184+ const oldEnd = this . lines . length ;
185+ if ( oldEnd <= startLine ) {
186+ return ;
187+ }
188+
189+ for ( let i = startLine ; i <= this . lines . length ; i ++ ) {
190+ this . lineStyles . delete ( i ) ;
191+ }
192+
193+ for ( let i = this . changedLines . length - 1 ; i >= 0 ; i -- ) {
194+ const changedLine = this . changedLines [ i ] ;
195+ if ( changedLine >= startLine ) {
196+ this . changedLines . splice ( i , 1 ) ;
197+ } else {
198+ break ;
199+ }
200+ }
201+
202+ this . lines = this . lines . splice ( 0 , startLine ) ;
203+ this . maxLine = Math . max ( 0 , startLine - 1 ) ;
204+
205+ this . savedCursorPosition = null ;
206+
207+ for ( const listener of this . listeners ) {
208+ listener . linesDeleted ( startLine , oldEnd ) ;
209+ }
210+ }
211+
212+ deleteTopLines ( linesCount ) {
213+ if ( linesCount <= 0 ) {
214+ return ;
215+ }
216+
217+ for ( let i = 0 ; i < linesCount ; i ++ ) {
218+ this . lineStyles . delete ( i ) ;
219+ }
220+
221+ for ( let i = 0 ; i < this . lines . length ; i ++ ) {
222+ const oldIndex = i + linesCount ;
223+ if ( this . lineStyles . has ( oldIndex ) ) {
224+ this . lineStyles . set ( i , this . lineStyles . get ( oldIndex ) ) ;
225+ this . lineStyles . delete ( oldIndex ) ;
226+ }
227+ }
228+
229+ this . lines = this . lines . splice ( linesCount ) ;
230+
231+ this . currentLine = Math . max ( 0 , this . currentLine - linesCount ) ;
232+
233+ this . savedCursorPosition = null ;
234+
235+ this . maxLine = Math . max ( 0 , this . lines . length - 1 ) ;
236+ this . changedLines = [ ] ;
237+
238+ for ( const listener of this . listeners ) {
239+ listener . cleared ( ) ;
240+ }
241+
242+ for ( let i = 0 ; i < this . lines . length ; i ++ ) {
243+ this . changedLines . push ( i ) ;
244+ }
245+ }
246+
183247 getStyle ( line ) {
184248 return this . lineStyles . get ( line ) ;
185249 }
@@ -534,7 +598,7 @@ class ClearLineHandler extends CommandHandler {
534598 if ( direction === 0 ) {
535599 terminal . clearLineToRight ( ) ;
536600 } else if ( direction === 1 ) {
537- terminal . clearLineToLeft ( ) ;
601+ terminal . clearLineToLeft ( terminal . currentPosition ) ;
538602 } else if ( direction === 2 ) {
539603 terminal . clearFullLine ( ) ;
540604 } else {
@@ -543,10 +607,31 @@ class ClearLineHandler extends CommandHandler {
543607 }
544608}
545609
610+ class ClearScreenHandler extends CommandHandler {
611+ constructor ( ) {
612+ super ( ) ;
613+ }
614+
615+ handle ( args , terminal ) {
616+ const direction = args [ 0 ] ;
617+
618+ if ( direction === 0 ) {
619+ terminal . deleteBottomLines ( terminal . currentLine + 1 ) ;
620+ } else if ( direction === 1 ) {
621+ terminal . deleteTopLines ( terminal . currentLine ) ;
622+ terminal . clearLineToLeft ( terminal . currentPosition + 1 ) ;
623+ } else if ( ( direction === 2 ) || ( direction === 3 ) ) {
624+ terminal . clear ( ) ;
625+ } else {
626+ console . log ( 'WARN! Unsupported [' + direction + 'J command' ) ;
627+ }
628+ }
629+ }
630+
546631const COMMAND_HANDLERS = new Map ( ) ;
547632COMMAND_HANDLERS . set ( 'm' , new SetGraphicsCommandHandler ( ) ) ;
548633COMMAND_HANDLERS . set ( 'K' , new ClearLineHandler ( ) ) ;
549- COMMAND_HANDLERS . set ( 'J' , null ) ;
634+ COMMAND_HANDLERS . set ( 'J' , new ClearScreenHandler ( ) ) ;
550635COMMAND_HANDLERS . set ( 'H' , new MoveCursorToPositionHandler ( ) ) ;
551636COMMAND_HANDLERS . set ( 'f' , new MoveCursorToPositionHandler ( ) ) ;
552637COMMAND_HANDLERS . set ( 'A' , new MoveCursorVerticallyHandler ( true ) ) ;
0 commit comments