@@ -310,40 +310,51 @@ static int FindCommonPrefixLength(string leftStr, string rightStr)
310310 // Make cursor invisible while we're rendering.
311311 _console . CursorVisible = false ;
312312
313- // Calculate what to render and where to start the rendering.
314- // TODO: Short circuit optimization when currentBuffer == previousBuffer.
315- int commonPrefixLength = FindCommonPrefixLength ( previousBuffer , currentBuffer ) ;
316-
317- if ( commonPrefixLength > 0 && commonPrefixLength == previousBuffer . Length )
313+ if ( currentBuffer == previousBuffer )
318314 {
319- // Previous buffer is a complete prefix of current buffer.
320- // Just append the new data.
321- var appendedData = currentBuffer . Substring ( commonPrefixLength ) ;
322- _console . Write ( appendedData ) ;
315+ // No-op, such as when selecting text or otherwise re-entering.
323316 }
324- else if ( commonPrefixLength > 0 )
325- {
326- // Buffers share a common prefix but previous buffer has additional content.
327- // Move cursor to where the difference starts, clear forward, and write the data.
328- var diffPoint = ConvertOffsetToPoint ( commonPrefixLength , buffer ) ;
329- _console . SetCursorPosition ( diffPoint . X , diffPoint . Y ) ;
330- var changedData = currentBuffer . Substring ( commonPrefixLength ) ;
331- _console . Write ( "\x1b [0J" ) ;
332- _console . Write ( changedData ) ;
333- }
334- else
317+ else if ( previousBuffer . Length == 0 )
335318 {
336- // No common prefix, rewrite entire buffer.
319+ // Previous buffer was empty so we just render the current buffer.
337320 _console . SetCursorPosition ( _initialX , _initialY ) ;
338- _console . Write ( "\x1b [0J" ) ;
339321 _console . Write ( currentBuffer ) ;
340322 }
323+ else
324+ {
325+ // Calculate what to render and where to start the rendering.
326+ int commonPrefixLength = FindCommonPrefixLength ( previousBuffer , currentBuffer ) ;
341327
328+ // If we're scrolling through history we always want to re-render.
329+ // Writing only the diff in this scenario is a weird UX.
330+ if ( commonPrefixLength > 0 && _anyHistoryCommandCount == 0 )
331+ {
332+ // We need to differentially render, possibly with a partial rewrite.
333+ if ( commonPrefixLength != previousBuffer . Length )
334+ {
335+ // The buffers share a common prefix but the previous buffer has additional content.
336+ // Move cursor to where the difference starts and clear so we can rewrite.
337+ var diffPoint = ConvertOffsetToPoint ( commonPrefixLength , buffer ) ;
338+ _console . SetCursorPosition ( diffPoint . X , diffPoint . Y ) ;
339+ _console . Write ( "\x1b [0J" ) ;
340+ } // Otherwise the previous buffer is a complete prefix and we just write.
341+
342+ var diffData = currentBuffer . Substring ( commonPrefixLength ) ;
343+ _console . Write ( diffData ) ;
344+ }
345+ else
346+ {
347+ // The buffers are completely different so we need to rewrite from the start.
348+ _console . SetCursorPosition ( _initialX , _initialY ) ;
349+ _console . Write ( "\x1b [0J" ) ;
350+ _console . Write ( currentBuffer ) ;
351+ }
352+ }
353+
342354 // If we had to wrap to render everything, update _initialY
343355 var endPoint = ConvertOffsetToPoint ( currentBuffer . Length , buffer ) ;
344356 if ( endPoint . Y >= bufferHeight )
345357 {
346-
347358 // We had to scroll to render everything, update _initialY.
348359 int offset = 1 ; // Base case to handle zero-indexing.
349360 if ( endPoint . X == 0 )
0 commit comments