Skip to content

Commit e390233

Browse files
committed
Basic safe rendering support for screen readers
1 parent 67b6fc7 commit e390233

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

PSReadLine/BasicEditing.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,8 @@ public static void BackwardDeleteChar(ConsoleKeyInfo? key = null, object arg = n
194194

195195
_singleton.RemoveTextToViRegister(startDeleteIndex, qty, BackwardDeleteChar, arg, !InViEditMode());
196196
_singleton._current = startDeleteIndex;
197-
_singleton.Render();
197+
// Moves cursor to startDeleteIndex (backwards probably) and then deletes qty
198+
_singleton.SafeRender($"\x1b[{qty}P", startDeleteIndex);
198199
}
199200
}
200201

@@ -218,7 +219,8 @@ private void DeleteCharImpl(int qty, bool orExit)
218219
{
219220
_current = Math.Max(0, _buffer.Length + ViEndOfLineFactor);
220221
}
221-
Render();
222+
// Deletes qty characters without moving the cursor
223+
_singleton.SafeRender($"\x1b[{qty}P");
222224
}
223225
}
224226
else if (orExit)

PSReadLine/KillYank.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ private void Kill(int start, int length, bool prepend)
7878
SaveEditItem(EditItemDelete.Create(killText, start));
7979
_buffer.Remove(start, length);
8080
_current = start;
81-
Render();
81+
// Deletes the rest of the line from start
82+
SafeRender("\x1b[K", start);
8283
if (_killCommandCount > 0)
8384
{
8485
if (prepend)

PSReadLine/PublicAPI.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ public static void Insert(char c)
8383
_singleton._buffer.Insert(_singleton._current, c);
8484
}
8585
_singleton._current += 1;
86-
_singleton.Render();
86+
// Renders the character (which moves the cursor forward one)
87+
_singleton.SafeRender(c.ToString());
8788
}
8889

8990
/// <summary>
@@ -105,7 +106,8 @@ public static void Insert(string s)
105106
_singleton._buffer.Insert(_singleton._current, s);
106107
}
107108
_singleton._current += s.Length;
108-
_singleton.Render();
109+
// Renders the string (which moves the cursor forward the string's length)
110+
_singleton.SafeRender(s);
109111
}
110112

111113
/// <summary>
@@ -147,6 +149,8 @@ public static void Replace(int start, int length, string replacement, Action<Con
147149
var str = _singleton._buffer.ToString(start, length);
148150
_singleton.SaveEditItem(EditItemDelete.Create(str, start));
149151
_singleton._buffer.Remove(start, length);
152+
// Moves cursor to start (backwards probably) and then deletes length
153+
_singleton.SafeRender($"\x1b[{length}P", start);
150154
if (replacement != null)
151155
{
152156
_singleton.SaveEditItem(EditItemInsertString.Create(replacement, start));
@@ -161,7 +165,8 @@ public static void Replace(int start, int length, string replacement, Action<Con
161165
if (useEditGroup)
162166
{
163167
_singleton.EndEditGroup(instigator, instigatorArg); // Instigator is needed for VI undo
164-
_singleton.Render();
168+
// Renders the string (which moves the cursor forward the string's length)
169+
_singleton.SafeRender(replacement);
165170
}
166171
}
167172

PSReadLine/Render.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,24 @@ private void RenderWithPredictionQueryPaused()
218218
Render();
219219
}
220220

221+
private void SafeRender(string s, int? cursor = null)
222+
{
223+
// Render as usual if we're not supporting a screen reader
224+
if (!_singleton.Options.ScreenReader)
225+
{
226+
Render();
227+
return;
228+
}
229+
230+
// Move the cursor if we have to
231+
if (cursor.HasValue)
232+
MoveCursor(cursor.Value);
233+
234+
// Directly write without re-rendering
235+
// This means using ANSI escapes for movement
236+
_console.Write(s);
237+
}
238+
221239
private void Render()
222240
{
223241
// If there are a bunch of keys queued up, skip rendering if we've rendered very recently.

0 commit comments

Comments
 (0)