-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Description
Currently, the System.Console class in provides two separate properties, CursorLeftand CursorTop that allow the user to change / read the position of the console cursor.
Unfortunately, there seems to be no public API that allows reading the cursor position "atomically" (e.g. both row and column position) although the underlying implementation does get/set the actual position atomically.
Conversly, there does exist a SetCursorPosition public method:
https://github.com/dotnet/corefx/blob/eec001d96a68376c0e504eb7635c8edec196f90f/src/System.Console/src/System/Console.cs#L306
Rational and Usage
The idea would be to be able to read the cursor position on its associated terminal/console in one atomic API call, unlike today, where users of the Console class often write code like:
var oldX = Console.CursorLeft;
var oldY = Console.CursotTop;
Console.SetCursorPosition(0, oldY + 10);
// Some console output goes out here
Console.SetCursorPosition(oldX, oldY);The proposed API would allow reading/setting the position in one API call that would also translate as one atomic system call / write to the underlying OS:
Console.GetCursorPosition(out var oldX, out var oldY);
Console.SetCursorPosition(0, oldY + 10);
// Some console output goes out here
Console.SetCursorPosition(oldX, oldY);The proposed change makes reading the console cursor position more readable, efficient (more on that later) and most importantly atomic, in the sense that the API will allow to ensure that the console cursor is/was in the reported position, unlike today, where the console cursor position can change in between calls to the getters/setters of CursorLeft and CursorTop.
Proposed API
namespace System
{
public static class Console
{
void GetCursorPosition(out int left, out int top);
}
}Details
- As mentioned above, the actual implementations already part of CoreFX do support atomic read/write of the cursor position both in Windows / Unix inside the respective
ConsolePalclasses:- Windows:
https://github.com/dotnet/corefx/blob/ec7a4c6e09d655421195580b7eea887000afc367/src/System.Console/src/System/ConsolePal.Windows.cs#L1078 - Unix:
https://github.com/dotnet/corefx/blob/ec7a4c6e09d655421195580b7eea887000afc367/src/System.Console/src/System/ConsolePal.Unix.cs#L348
- Windows:
- The current implementation, esp. in the case of Unix is very heavy and complex, making calling it twice in order to read the complete position is somewhat wasteful, although this is probably a minor consideration in the grand scheme of things.
- For the same reason, In the case of Unix / VT100, implementing atomic reading in user-code (outside CoreFX) is very complex due to the various VT100 quirks that I will not go into here (Reading
GetCursorPositioninConsolePal.Unix.cslinked above makes that abundantly clear).