Skip to content

SpectreConsoleProvider.SetCursorVisibility moves the cursor and toggles visibility on System.Console instead of the injected IAnsiConsole #153

Description

@matt-edmondson

What's wrong

In TUI/Services/SpectreConsoleProvider.cs (around lines 101-105):

public void SetCursorVisibility(bool visible)
{
    _console.Cursor.SetPosition(Console.CursorLeft + 1, Console.CursorTop + 1);
    Console.CursorVisible = visible;
}
  • It moves the cursor, which a visibility call shouldn't do. The target position comes from the process's real System.Console, not the console the provider was given.
  • The show/hide itself goes to System.Console.CursorVisible, so it never reaches the injected IAnsiConsole.
  • GetCursorPosition() (around line 141) also reads System.Console.

Failure scenario

I built the provider with an IAnsiConsole over a StringWriter, the same setup SpectreConsoleProviderTests uses, and called SetCursorVisibility(false).

  • Actual: the captured output is ESC[1;1H, a stray cursor move. No hide sequence is written. The hide/show goes to the real stdout instead.
  • Expected: ESC[?25l is written to the injected console, with no cursor movement.

With the default AnsiConsole.Console this mostly looks fine. With a redirected, remote or test console, the cursor jumps and the visibility change goes to the wrong terminal.

Suggested fix / acceptance criteria

  • Replace the body with _console.Cursor.Show(visible); and drop the SetPosition line.
  • Add a test asserting that the captured output contains ESC[?25l / ESC[?25h and no CUP sequence.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workingreadyFully specified; implement as written

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions