@@ -136,14 +136,16 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
136136
137137 function getPreviewPos ( ) {
138138 const displayPos = repl . _getDisplayPos ( `${ repl . _prompt } ${ repl . line } ` ) ;
139- const cursorPos = repl . getCursorPos ( ) ;
140- const rows = 1 + displayPos . rows - cursorPos . rows ;
141- return { rows, cols : cursorPos . cols } ;
139+ const cursorPos = repl . line . length !== repl . cursor ?
140+ repl . getCursorPos ( ) :
141+ displayPos ;
142+ return { displayPos, cursorPos } ;
142143 }
143144
144145 const clearPreview = ( ) => {
145146 if ( inputPreview !== null ) {
146- const { rows } = getPreviewPos ( ) ;
147+ const { displayPos, cursorPos } = getPreviewPos ( ) ;
148+ const rows = displayPos . rows - cursorPos . rows + 1 ;
147149 moveCursor ( repl . output , 0 , rows ) ;
148150 clearLine ( repl . output ) ;
149151 moveCursor ( repl . output , 0 , - rows ) ;
@@ -153,12 +155,25 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
153155 if ( completionPreview !== null ) {
154156 // Prevent cursor moves if not necessary!
155157 const move = repl . line . length !== repl . cursor ;
158+ let pos , rows ;
156159 if ( move ) {
157- cursorTo ( repl . output , repl . _prompt . length + repl . line . length ) ;
160+ pos = getPreviewPos ( ) ;
161+ cursorTo ( repl . output , pos . displayPos . cols ) ;
162+ rows = pos . displayPos . rows - pos . cursorPos . rows ;
163+ moveCursor ( repl . output , 0 , rows ) ;
164+ }
165+ const totalLine = `${ repl . _prompt } ${ repl . line } ${ completionPreview } ` ;
166+ const newPos = repl . _getDisplayPos ( totalLine ) ;
167+ // Minimize work for the terminal. It is enough to clear the right part of
168+ // the current line in case the preview is visible on a single line.
169+ if ( newPos . rows === 0 || ( pos && pos . displayPos . rows === newPos . rows ) ) {
170+ clearLine ( repl . output , 1 ) ;
171+ } else {
172+ clearScreenDown ( repl . output ) ;
158173 }
159- clearLine ( repl . output , 1 ) ;
160174 if ( move ) {
161- cursorTo ( repl . output , repl . _prompt . length + repl . cursor ) ;
175+ cursorTo ( repl . output , pos . cursorPos . cols ) ;
176+ moveCursor ( repl . output , 0 , - rows ) ;
162177 }
163178 completionPreview = null ;
164179 }
@@ -198,17 +213,6 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
198213
199214 const suffix = prefix . slice ( completeOn . length ) ;
200215
201- const totalLength = repl . line . length +
202- repl . _prompt . length +
203- suffix . length +
204- ( repl . useColors ? 0 : 4 ) ;
205-
206- // TODO(BridgeAR): Fix me. This should not be necessary. See similar
207- // comment in `showPreview()`.
208- if ( totalLength > repl . columns ) {
209- return ;
210- }
211-
212216 if ( insertPreview ) {
213217 repl . _insertString ( suffix ) ;
214218 return ;
@@ -220,11 +224,17 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
220224 `\u001b[90m${ suffix } \u001b[39m` :
221225 ` // ${ suffix } ` ;
222226
227+ const { cursorPos, displayPos } = getPreviewPos ( ) ;
223228 if ( repl . line . length !== repl . cursor ) {
224- cursorTo ( repl . output , repl . _prompt . length + repl . line . length ) ;
229+ cursorTo ( repl . output , displayPos . cols ) ;
230+ moveCursor ( repl . output , 0 , displayPos . rows - cursorPos . rows ) ;
225231 }
226232 repl . output . write ( result ) ;
227- cursorTo ( repl . output , repl . _prompt . length + repl . cursor ) ;
233+ cursorTo ( repl . output , cursorPos . cols ) ;
234+ const totalLine = `${ repl . _prompt } ${ repl . line } ${ suffix } ` ;
235+ const newPos = repl . _getDisplayPos ( totalLine ) ;
236+ const rows = newPos . rows - cursorPos . rows - ( newPos . cols === 0 ? 1 : 0 ) ;
237+ moveCursor ( repl . output , 0 , - rows ) ;
228238 } ) ;
229239 }
230240
@@ -288,6 +298,7 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
288298 } , ( ) => callback ( new ERR_INSPECTOR_NOT_AVAILABLE ( ) ) ) ;
289299 }
290300
301+ // TODO(BridgeAR): Prevent previews while pasting code.
291302 const showPreview = ( ) => {
292303 // Prevent duplicated previews after a refresh.
293304 if ( inputPreview !== null ) {
@@ -373,12 +384,12 @@ function setupPreview(repl, contextSymbol, bufferSymbol, active) {
373384 `\u001b[90m${ inspected } \u001b[39m` :
374385 `// ${ inspected } ` ;
375386
376- const { rows : previewRows , cols : cursorCols } = getPreviewPos ( ) ;
377- if ( previewRows !== 1 )
378- moveCursor ( repl . output , 0 , previewRows - 1 ) ;
387+ const { cursorPos , displayPos } = getPreviewPos ( ) ;
388+ const rows = displayPos . rows - cursorPos . rows ;
389+ moveCursor ( repl . output , 0 , rows ) ;
379390 const { cols : resultCols } = repl . _getDisplayPos ( result ) ;
380391 repl . output . write ( `\n${ result } ` ) ;
381- moveCursor ( repl . output , cursorCols - resultCols , - previewRows ) ;
392+ moveCursor ( repl . output , cursorPos . cols - resultCols , - rows - 1 ) ;
382393 } ) ;
383394 } ;
384395
@@ -452,8 +463,8 @@ function setupReverseSearch(repl) {
452463 // Reset the already matched set in case the direction is changed. That
453464 // way it's possible to find those entries again.
454465 alreadyMatched . clear ( ) ;
466+ dir = keyName ;
455467 }
456- dir = keyName ;
457468 return true ;
458469 }
459470
@@ -598,16 +609,14 @@ function setupReverseSearch(repl) {
598609
599610 // Clear screen and write the current repl.line before exiting.
600611 cursorTo ( repl . output , promptPos . cols ) ;
601- if ( promptPos . rows !== 0 )
602- moveCursor ( repl . output , 0 , promptPos . rows ) ;
612+ moveCursor ( repl . output , 0 , promptPos . rows ) ;
603613 clearScreenDown ( repl . output ) ;
604614 if ( repl . line !== '' ) {
605615 repl . output . write ( repl . line ) ;
606616 if ( repl . line . length !== repl . cursor ) {
607617 const { cols, rows } = repl . getCursorPos ( ) ;
608618 cursorTo ( repl . output , cols ) ;
609- if ( rows !== 0 )
610- moveCursor ( repl . output , 0 , rows ) ;
619+ moveCursor ( repl . output , 0 , rows ) ;
611620 }
612621 }
613622 }
0 commit comments