Table of Contents

Class Crt

Namespace
Retro.Crt
Assembly
Retro.Crt.dll

Pascal CRT-Unit-style console. Static, stateless from the caller's view — just the verbs, plus a small WithStyle(Color?, Color?, bool) scope for transient styling.

public static class Crt
Inheritance
Crt
Inherited Members

Fields

DefaultHeight

Height fallback used when the terminal is not measurable.

public const int DefaultHeight = 24

Field Value

int

DefaultWidth

Width fallback used when the terminal is not measurable.

public const int DefaultWidth = 80

Field Value

int

FillWidth

Sentinel for the width parameter on widgets that support "fill the terminal". Banner and ProgressBar treat this as WindowWidth at render time.

public const int FillWidth = -1

Field Value

int

Properties

ColorEnabled

True when ANSI escapes will actually reach the terminal. False when output is redirected, NO_COLOR is set, or VT enablement failed on Windows. Equivalent to Depth != ColorDepth.None.

public static bool ColorEnabled { get; }

Property Value

bool

CurrentTheme

The active theme, or null when none is in effect. Set via UseTheme(Theme) for the duration of the returned scope. Widgets that accept an optional color (Banner, Log, ProgressBar, Spinner, Table, Prompt, Typewriter) fall back to a sensible slot from this theme when the caller doesn't supply one, so themed output stays consistent without threading colors through every call site.

public static Theme? CurrentTheme { get; }

Property Value

Theme?

CursorLeft

Current cursor column (0-based), or 0 when the host can't report it (output redirected, no console attached). Use this if you want to anchor your own multi-line layout to wherever the cursor sits after a GotoXY(int, int). Never throws.

public static int CursorLeft { get; }

Property Value

int

Depth

What this terminal can render. Truecolor on modern terminals (Windows Terminal, iTerm2, kitty, …); Xterm256 on most legacy 256-color terminals; Standard16 on basic VTs; None when output is redirected, dumb, or NO_COLOR is set. Truecolor and 256-color values are quantized down to whatever this depth supports before emission.

public static ColorDepth Depth { get; }

Property Value

ColorDepth

IsInteractive

True when stdout is a real, escape-processing terminal — independent of ColorEnabled. Use this to gate animation (in-place redraws via CR, hide/show cursor, anchor indents): a terminal with NO_COLOR=1 is still interactive, just without colors. False for redirected output, TERM=dumb, and Windows hosts where VT enablement failed.

public static bool IsInteractive { get; }

Property Value

bool

Sink

The TextWriter Retro.Crt currently writes to. Defaults to Out (so Console.SetOut transparently re-targets us); a WithSink(TextWriter) scope overrides it for the scope's lifetime so all widgets — Crt, Banner, ProgressBar, Spinner, Prompt, Table, Typewriter — emit to the same destination.

public static TextWriter Sink { get; }

Property Value

TextWriter

WindowHeight

Visible terminal height in cells, with a sensible default when the host can't report it. Defaults to DefaultHeight; never throws.

public static int WindowHeight { get; }

Property Value

int

WindowWidth

Visible terminal width in cells, with a sensible default when the host can't report it (output redirected, no console attached, daemon, …). Defaults to DefaultWidth; never throws.

public static int WindowWidth { get; }

Property Value

int

Methods

Bell()

Pascal Sound-flavoured beep — emits BEL (\a) and flushes so the terminal actually rings. No-op when output is redirected or the host isn't a real terminal: piping a bell into a file is just noise. BEL predates ANSI so this works even with NO_COLOR or on legacy hosts that never enabled VT.

public static void Bell()

ClrEol()

public static void ClrEol()

ClrScr()

public static void ClrScr()

GotoXY(int, int)

1-based cursor position, like the original CRT unit.

public static void GotoXY(int column, int row)

Parameters

column int
row int

PaintBackground()

Fill every visible cell of the terminal viewport with the active SGR background color by writing spaces. Set the bg first via TextBackground(Color) or WithStyle(Color?, Color?, bool) — without an explicit bg this is effectively a no-op clear. ECMA-48 says ClrScr() erases with the current SGR background, but real-world honouring of that (the bce capability) varies, so this is the bulletproof variant. Pairs naturally with UseAlternateScreen() for vim/less-style fullscreen takeovers without touching the user's shell. No-op when ANSI is unavailable. Cursor returns to (1, 1).

public static void PaintBackground()

ResetColor()

public static void ResetColor()

TextBackground(Color)

public static void TextBackground(Color color)

Parameters

color Color

TextColor(Color)

public static void TextColor(Color color)

Parameters

color Color

UseAlternateScreen()

Take over the terminal with the alternate screen buffer for the duration of the returned scope: the user's previous shell content is preserved by the terminal itself and restored verbatim when the scope disposes — vim / less / htop style. Cleared on entry, no scrollback leak on exit.

public static IDisposable UseAlternateScreen()

Returns

IDisposable

Remarks

No-op when output is redirected or the host isn't a real terminal. Nests by reference count: only the outermost enter/leave actually flips the buffer. A Console.CancelKeyPress handler and a ProcessExit handler are registered lazily on first use so the user's shell isn't left stuck on the alternate screen if the process is Ctrl-C'd or killed before the scope disposes.

UseBracketedPaste()

Ask the terminal to wrap clipboard pastes in ESC[200~ / ESC[201~ sentinels for the duration of the returned scope, so applications can distinguish typed input from injected text. Disposing emits the matching disable escape so the user's shell isn't left in bracketed-paste mode after your app exits.

public static IDisposable UseBracketedPaste()

Returns

IDisposable

Remarks

No-op when output is redirected or the host isn't a real terminal. Nests by reference count. CancelKeyPress and ProcessExit handlers are registered lazily so a Ctrl-C doesn't leave the user's shell in paste mode.

UseHiddenCursor()

Hide the terminal cursor for the duration of the returned scope — pairs naturally with full-screen takeovers (game loops, TUI redraws) where a parked, blinking cursor would flicker on top of the painted frame. Disposing emits the show-cursor escape so the user's shell isn't left blind after your app exits.

public static IDisposable UseHiddenCursor()

Returns

IDisposable

Remarks

No-op when output is redirected or the host isn't a real terminal. Nests by reference count. CancelKeyPress and ProcessExit handlers are registered lazily so a Ctrl-C always restores the cursor.

UseMouse()

Ask the terminal to send mouse events as SGR-encoded reports (xterm mode 1006) for the duration of the returned scope, with any-event tracking (mode 1003) so motion, drag, and wheel are included alongside press / release. Disposing emits the matching disable escapes so the user's shell doesn't keep receiving reports after your app exits.

public static IDisposable UseMouse()

Returns

IDisposable

Remarks

Emit-side only — this configures what the terminal SENDS, but you still need a stdin reader in raw mode to actually receive the bytes. Pair with TryParseMouse(ReadOnlySpan<char>, out MouseEvent, out int) (or the upcoming RawMode + input loop) to consume them.

No-op when output is redirected or the host isn't a real terminal. Nests by reference count: only the outermost enter / leave actually flips the mode. CancelKeyPress and ProcessExit handlers are registered lazily so a Ctrl-C doesn't leave the user's shell drowning in mouse reports.

UseTheme(Theme)

Apply theme as the implicit color source for the duration of the returned scope. Emits the theme's foreground as SGR so subsequent plain Crt.Write/WriteLine calls render in that color; widgets with a color/fg parameter fall back to the matching theme slot when their argument is null. Themes do not own a background — set one explicitly per call via WithStyle(Color?, Color?, bool) if needed. Disposing the scope emits RESET and restores the previous theme, if any. Nests cleanly.

public static IDisposable UseTheme(Theme theme)

Parameters

theme Theme

Returns

IDisposable

WithSink(TextWriter)

Route all Retro.Crt output to sink for the duration of the returned scope. Also routes Log (both OutSink and ErrSink) so a single scope captures everything. Restores the previous overrides on dispose; nests cleanly.

public static IDisposable WithSink(TextWriter sink)

Parameters

sink TextWriter

Returns

IDisposable

WithStyle(Color?, Color?, bool)

Apply optional foreground/background/bold for the duration of the returned scope. Disposing restores the previous styling via a single RESET.

public static IDisposable WithStyle(Color? fg = null, Color? bg = null, bool bold = false)

Parameters

fg Color?
bg Color?
bold bool

Returns

IDisposable

Write(string)

public static void Write(string s)

Parameters

s string

WriteLine()

public static void WriteLine()

WriteLine(string)

public static void WriteLine(string s)

Parameters

s string