Skip to content

Commit fb7d377

Browse files
committed
Logic and UX improvements to screen reader renderer
1 parent fc537bf commit fb7d377

File tree

1 file changed

+34
-23
lines changed

1 file changed

+34
-23
lines changed

PSReadLine/Render.cs

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)