closeout
API reference

closeout/cursor

Every export of closeout/cursor, with its signature and doc comment: showCursor, hideCursor, alternateScreen, rawMode, HIDE_CURSOR, SHOW_CURSOR and 2 more, plus 3 types.

import { showCursor, hideCursor, alternateScreen, … } from 'closeout/cursor';

Functions

alternateScreen

Enter the alternate screen, and register leaving it.

Returns the function that leaves it, with {@link hideCursor}'s contract: once only, and calling it early unregisters the exit handler. A non-TTY gets nothing in either direction.

function alternateScreen(stream: OutputStream, onExit: Registrar): () => void;
ParameterType
streamOutputStream
onExitRegistrar

Returns () => void

hideCursor

Hide the cursor, and register its restore.

Returns the function that shows it again. Calling that function unregisters the handler too, so a program that cleans up normally leaves nothing behind for exit to do.

function hideCursor(stream: OutputStream, onExit: Registrar): () => void;
ParameterType
streamOutputStream
onExitRegistrar

Returns () => void

rawMode

Turn raw mode on, and register turning it off.

Only a mode this call turned on is turned off. If the input is already raw, somebody else owns that state — a prompt library, the program itself — and switching it off at exit would take it from them; the call changes nothing and returns a no-op. The same holds for an input that is not a terminal or has no setRawMode: there is no mode to change.

function rawMode(input: InputStream, onExit: Registrar): () => void;
ParameterType
inputInputStream
onExitRegistrar

Returns () => void

showCursor

Show the cursor. Safe to call when it was never hidden, and safe to call twice — the sequence is idempotent, which is what makes it usable from an exit path that may run after a caller has already cleaned up.

A non-TTY gets nothing: writing escape sequences into a pipe corrupts the output the pipe exists to carry.

function showCursor(stream: OutputStream): void;
ParameterType
streamOutputStream

Returns void

Constants

ENTER_ALTERNATE_SCREEN

The alternate screen, DEC private mode 1049: entering saves the cursor and switches to a blank buffer; leaving switches back and restores it, so the user's scrollback is as it was.

const ENTER_ALTERNATE_SCREEN = "\u001B[?1049h";

HIDE_CURSOR

The sequences this layer exists to undo, published because they are its vocabulary: anything that hides a cursor owes a show on every exit path, and a caller writing them by hand should be writing the same bytes we restore.

const HIDE_CURSOR = "\u001B[?25l";

LEAVE_ALTERNATE_SCREEN

const LEAVE_ALTERNATE_SCREEN = "\u001B[?1049l";

SHOW_CURSOR

const SHOW_CURSOR = "\u001B[?25h";

Interfaces

InputStream

The half of tty.ReadStream raw mode needs. setRawMode is optional because a piped process.stdin has none, and a caller should be able to pass process.stdin either way.

interface InputStream {
    isTTY?: boolean;
    /** Node's own record of the mode, read to learn whether somebody else turned it on. */
    isRaw?: boolean;
    setRawMode?(mode: boolean): unknown;
}

OutputStream

The half of NodeJS.WriteStream this needs, so a test can pass a recorder.

interface OutputStream {
    write(chunk: string): unknown;
    isTTY?: boolean;
}

Types

Registrar

Where a pairing registers its undo — closeout's registry, or a caller's own.

type Registrar = (handler: () => void) => () => void;

On this page