From 50241b92c8de236f35df4508434346a13ef37aeb Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Mon, 7 Jul 2025 20:11:54 +1000 Subject: [PATCH 01/25] Create unstable_ansi.ts --- cli/unstable_ansi.ts | 164 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 cli/unstable_ansi.ts diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts new file mode 100644 index 000000000000..141a7a4f8214 --- /dev/null +++ b/cli/unstable_ansi.ts @@ -0,0 +1,164 @@ +import { delay } from "@std/async/delay"; +export class Ansi { + /** + * Inserts `x` spaces at the cursor position. Shifting existing line content + * to the right. Overflow is discarded. + */ + static insertBlanks(x = 1): string { + return `\x1b[${x}@`; + } + /** + * Inserts `x` lines at cursor position. Shifting current line and below + * down. Overflow is discarded. + */ + static insertLines(x = 1): string { + return `\x1b[${x}L`; + } + /** + * Deletes `x` lines at cursor position. Shifting below lines up. + */ + static deleteLines(x = 1): string { + return `\x1b[${x}M`; + } + /** + * Deletes `x` characters at cursor position and to the right. Shifting line + * content left. + */ + static deleteCharacters(x = 1): string { + return `\x1b[${x}P`; + } + /** + * Moves cursor position up `x` lines or up to the top margin. + */ + static moveCursorUp(x = 1): string { + return `\x1b[${x}A`; + } + /** + * Moves cursor position down `x` lines or up to the bottom margin. + */ + static moveCursorDown(x = 1): string { + return `\x1b[${x}B`; + } + /** + * Moves cursor position `x` columns right or up to the right margin. + */ + static moveCursorRight(x = 1): string { + return `\x1b[${x}C`; + } + /** + * Moves cursor position `x` columns left or up to the left margin. + */ + static moveCursorLeft(x = 1): string { + return `\x1b[${x}D`; + } + /** + * Moves cursor position `x` lines down or up to the bottom margin, and to + * the beginning of the line. + */ + static moveCursorDownStart(x = 1): string { + return `\x1b[${x}E`; + } + /** + * Moves cursor position `x` lines up or up to the top of the margin, and to the beginning of the line. + */ + static moveCursorUpStart(x = 1): string { + return `\x1b[${x}F`; + } + /** + * Sets cursor column position to `x` or up to the sides of the margins. + */ + static setCursorColumn(x = 1): string { + return `\x1b[${x}G`; + } + /** + * Sets cursor position to `x` line and `y` column or up to the margin. + */ + static setCursorPosition(x = 1, y = 1): string { + return `\x1b[${x};${y}H`; + } + /** + * Moves cursor position `x` tab stops right or up to the right margin. + */ + static moveCursorRightTab(x = 1): string { + return `\x1b[${x}I`; + } + /** + * Moves cursor position `x` tab stops left or up to the left margin. + */ + static moveCursorLeftTab(x = 1): string { + return `\x1b[${x}Z`; + } + /** + * Erases content of lines below cursor position and content to the right on + * the same line as cursor. + */ + static get eraseDisplayAfterCursor(): string { + return "\x1b[0J"; + } + /** + * Erases content of lines above cursor position and content to the left on + * the same line eas cursor. + */ + static get eraseDisplayBeforeCursor(): string { + return "\x1b[1J"; + } + /** + * Erases all content. + */ + static get eraseDisplay(): string { + return "\x1b[2J"; + } + /** + * Erases line content to the right of cursor position. + */ + static get eraseLineAfterCursor(): string { + return "\x1b[0K"; + } + /** + * Erases line content to the left of cursor position. + */ + static get eraseLineBeforeCursor(): string { + return "\x1b[1K"; + } + /** + * Erases entire line content. + */ + static get eraseLine(): string { + return "\x1b[2K"; + } + /** + * Scrolls the scrollable region `x` lines up. Inserts blank lines at the + * bottom of the scrollable region. + */ + static scrollDownAndInsert(x = 1): string { + return `\x1b[${x}S`; + } + /** + * Scroll the scrollable region `x` lines down. Insert blank lines at the top of the scrollable region + */ + static scrollUpAndInsert(x = 1): string { + return `\x1b[${x}T`; + } + /** + * Erases `x` characters at cursor position and to the right. + */ + static eraseCharacters(x = 1): string { + return `\x1b[${x}X`; + } +} + +const encoder = new TextEncoder(); +async function write(text: string): Promise { + await Deno.stderr.write(encoder.encode(text)); +} + +const steps: string[] = [ + "Hello World\nHello World\nHello World", + "\x1b[1 t\x07", +]; + +for (const step of steps) { + await write(step); + await delay(1000); +} +await write("\n"); From ff46743537b326e1d3d0e932b2a193f2f7b3f498 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Mon, 7 Jul 2025 23:14:13 +1000 Subject: [PATCH 02/25] Update unstable_ansi.ts --- cli/unstable_ansi.ts | 222 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 191 insertions(+), 31 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index 141a7a4f8214..4f1e26eed0a8 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -1,15 +1,90 @@ -import { delay } from "@std/async/delay"; +// Copyright 2018-2025 the Deno authors. MIT license. + +// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html +// TODO: CSI Ps n + export class Ansi { + /** + * Causes content on the current line to enlarge, showing only the top half + * of characters with each character taking up two columns. Can be used in + * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to + * make text appear twice as big. + */ + static get doubleHeightTop(): string { + return "\x1b#3"; + } + /** + * Causes content on the current line to enlarge, showing only the bottom + * half of the characters with each character taking up two columns. Can be used in combination with {@linkcode Ansi.doubleHeightTop} on the previous line to make text appear twice as big. + */ + static get doubleHeightBottom(): string { + return "\x1b#4"; + } + /** + * Causes content on the current line to shrink down to a single column, + * essentally reverting the effects of {@linkcode Ansi.doubleHeightTop}, {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. + */ + static get singleWidth(): string { + return "\x1b#5"; + } + /** + * Causes content on the current line to stretch out, with each character + * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth} + */ + static get doubleWidth(): string { + return "\x1b#6"; + } + /** + * Saves current cursor position that can later be restored with + * {@linkcode Ansi.restoreCursorPosition}. + */ + static get saveCursorPosition(): string { + return "\x1b7"; + } + /** + * Restores cursor position that was earlier saved with + * {@linkcode Ansi.saveCursorPosition}. + */ + static get restoreCursorPosition(): string { + return "\x1b8"; + } + static get keypadApplicationMode(): string { + return "\x1b="; + } + static get keypadNormalMode(): string { + return "\x1b>"; + } + /** + * This is a full reset of the terminal, reverting it back to its original + * default settings, clearing the screen, resetting modes, colors, character + * sets and more. Essentally making the terminal behave as if it were just + * started by the user. This command is very disruptive to the user. Also see + * {@linkcode Ansi.softReset}. + */ + static get hardReset(): string { + return "\x1bc"; + } + /** + * This command resets many settings to their inital state without fully + * reinitalising the terminal like {@linkcode Ansi.hardReset}. It preserves + * things like cursor position and display content, but clears modes, + * character sets, etc. Should probably be called when exiting the program. + */ + static get softReset(): string { + return "\x1b[!p"; + } /** * Inserts `x` spaces at the cursor position. Shifting existing line content - * to the right. Overflow is discarded. + * to the right. Cursor position does not change. Characters that exit the + * display are discarded. */ - static insertBlanks(x = 1): string { + static insertSpace(x = 1): string { return `\x1b[${x}@`; } /** * Inserts `x` lines at cursor position. Shifting current line and below - * down. Overflow is discarded. + * down. Cursor position does not change. Characters that exit the display + * are discarded. */ static insertLines(x = 1): string { return `\x1b[${x}L`; @@ -53,25 +128,35 @@ export class Ansi { } /** * Moves cursor position `x` lines down or up to the bottom margin, and to - * the beginning of the line. + * the beginning of that line. */ static moveCursorDownStart(x = 1): string { return `\x1b[${x}E`; } /** - * Moves cursor position `x` lines up or up to the top of the margin, and to the beginning of the line. + * Moves cursor position `x` lines up or up to the top of the margin, and to + * the beginning of that line. */ static moveCursorUpStart(x = 1): string { return `\x1b[${x}F`; } /** - * Sets cursor column position to `x` or up to the sides of the margins. + * Sets cursor position to column `x` or up to the sides of the margins. + * Columns begin at `1` not `0`. */ static setCursorColumn(x = 1): string { return `\x1b[${x}G`; } /** - * Sets cursor position to `x` line and `y` column or up to the margin. + * Sets cursor position to line `x` or down to the bottom of the margin. + * Lines begin at `1` not `0`. + */ + static setCursorLine(x = 1): string { + return `\x1b[${x}d`; + } + /** + * Sets cursor position to `x` line and `y` column or up to the margin. Lines + * and columns begin at `1` not `0`. */ static setCursorPosition(x = 1, y = 1): string { return `\x1b[${x};${y}H`; @@ -97,7 +182,7 @@ export class Ansi { } /** * Erases content of lines above cursor position and content to the left on - * the same line eas cursor. + * the same line as cursor. */ static get eraseDisplayBeforeCursor(): string { return "\x1b[1J"; @@ -127,38 +212,113 @@ export class Ansi { return "\x1b[2K"; } /** - * Scrolls the scrollable region `x` lines up. Inserts blank lines at the - * bottom of the scrollable region. + * Erases `x` characters at cursor position and to the right. + */ + static eraseCharacters(x = 1): string { + return `\x1b[${x}X`; + } + /** + * Shifts content within the scrollable region up `x` lines, inserting blank + * lines at the bottom of the scrollable region. */ - static scrollDownAndInsert(x = 1): string { + static shiftUpAndInsert(x = 1): string { return `\x1b[${x}S`; } /** - * Scroll the scrollable region `x` lines down. Insert blank lines at the top of the scrollable region + * Shifts content within the scrollable region down `x` lines, inserting + * blank lines at the top of the scrollable region. */ - static scrollUpAndInsert(x = 1): string { + static shiftDownAndInsert(x = 1): string { return `\x1b[${x}T`; } /** - * Erases `x` characters at cursor position and to the right. + * Repeats last graphic character printed `x` times at cursor position. */ - static eraseCharacters(x = 1): string { - return `\x1b[${x}X`; + static repeatLastCharacter(x = 1): string { + return `\x1b[${x}b`; + } + /** + * Causes existing characters to the right of the cursor position to shift + * right as new characters are written. Opposite of + * {@linkcode Ansi.replaceMode}. + */ + static get insertMode(): string { + return "\x1b[4h"; + } + /** + * Causes existing characters to be overwritten at the cursor position by new + * characters. See also {@linkcode Ansi.insertMode}. + */ + static get replaceMode(): string { + return "\x1b[4l"; + } + /** + * Causes top and bottom margins to shrink to scrollable region (See + * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving + * to the lines outside it. + */ + static get enableOriginMode(): string { + return "\x1b[?6h"; + } + /** + * Causes the top and bottom margins to enlarge to the user's display. See + * {@linkcode Ansi.enableOriginMode}. + */ + static get disableOriginMode(): string { + return "\x1b[?6l"; + } + /** + * Causes cursor to automatically move to the next line when it hits the + * end of the current line to continue writing. See also + * {@linkcode Ansi.disableAutoWrap}. + */ + static get enableAutoWrap(): string { + return "\x1b[?7h"; + } + /** + * Causes cursor to remain on the same line when it hits the end of the + * current line. See also {@linkcode Ansi.enableAutoWrap}. + */ + static get disableAutoWrap(): string { + return "\x1b[?7l"; + } + /** + * Sets the cursor animation style. + */ + static setCursorStyle(x: CursorStyle): string { + return `\x1b[${x} q`; + } + /** + * Causes cursor position to be visible to the user. See also + * {@linkcode Ansi.hideCursor}. + */ + static get showCursor(): string { + return "\x1b[?25h"; + } + /** + * Causes cursor position to be hidden from the user. See also + * {@linkcode Ansi.showCursor}. + */ + static get hideCursor(): string { + return "\x1b[?25l"; + } + /** + * Sets the scrollable region of the display. Allowing either or both the top + * and bottom lines to not have their content moved when the scrolling region + * is updated. `x` is the top line of the scrollable region. `y` is the + * bottom line of the scrollable region. + */ + static setScrollableRegion(x = 1, y?: number): string { + y ??= Deno.consoleSize().rows; + return `\x1b[${x};${y}r`; } } -const encoder = new TextEncoder(); -async function write(text: string): Promise { - await Deno.stderr.write(encoder.encode(text)); -} - -const steps: string[] = [ - "Hello World\nHello World\nHello World", - "\x1b[1 t\x07", -]; - -for (const step of steps) { - await write(step); - await delay(1000); +export const enum CursorStyle { + BlinkingBlock = 1, + SteadyBlock = 2, + BlinkingUnderline = 3, + SteadyUnderline = 4, + BlinkingBar = 5, + SteadyBar = 6, } -await write("\n"); From 7417e1a91d4a0bd7ec92ddd1ac630821e9ed1fcc Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:15:08 +1000 Subject: [PATCH 03/25] fmt --- cli/unstable_ansi.ts | 148 +++++++++++++++++++++++++++---------------- 1 file changed, 93 insertions(+), 55 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index 4f1e26eed0a8..e962bfdccad7 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -13,13 +13,17 @@ export class Ansi { static get doubleHeightTop(): string { return "\x1b#3"; } + /** * Causes content on the current line to enlarge, showing only the bottom - * half of the characters with each character taking up two columns. Can be used in combination with {@linkcode Ansi.doubleHeightTop} on the previous line to make text appear twice as big. + * half of the characters with each character taking up two columns. Can be + * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous + * line to make text appear twice as big. */ static get doubleHeightBottom(): string { return "\x1b#4"; } + /** * Causes content on the current line to shrink down to a single column, * essentally reverting the effects of {@linkcode Ansi.doubleHeightTop}, {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. @@ -27,6 +31,7 @@ export class Ansi { static get singleWidth(): string { return "\x1b#5"; } + /** * Causes content on the current line to stretch out, with each character * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth} @@ -34,6 +39,7 @@ export class Ansi { static get doubleWidth(): string { return "\x1b#6"; } + /** * Saves current cursor position that can later be restored with * {@linkcode Ansi.restoreCursorPosition}. @@ -41,6 +47,7 @@ export class Ansi { static get saveCursorPosition(): string { return "\x1b7"; } + /** * Restores cursor position that was earlier saved with * {@linkcode Ansi.saveCursorPosition}. @@ -48,12 +55,7 @@ export class Ansi { static get restoreCursorPosition(): string { return "\x1b8"; } - static get keypadApplicationMode(): string { - return "\x1b="; - } - static get keypadNormalMode(): string { - return "\x1b>"; - } + /** * This is a full reset of the terminal, reverting it back to its original * default settings, clearing the screen, resetting modes, colors, character @@ -64,6 +66,7 @@ export class Ansi { static get hardReset(): string { return "\x1bc"; } + /** * This command resets many settings to their inital state without fully * reinitalising the terminal like {@linkcode Ansi.hardReset}. It preserves @@ -73,6 +76,7 @@ export class Ansi { static get softReset(): string { return "\x1b[!p"; } + /** * Inserts `x` spaces at the cursor position. Shifting existing line content * to the right. Cursor position does not change. Characters that exit the @@ -81,6 +85,22 @@ export class Ansi { static insertSpace(x = 1): string { return `\x1b[${x}@`; } + + /** + * Deletes `x` characters at cursor position and to the right. Shifting line + * content left. + */ + static deleteCharacters(x = 1): string { + return `\x1b[${x}P`; + } + + /** + * Erases `x` characters at cursor position and to the right. + */ + static eraseCharacters(x = 1): string { + return `\x1b[${x}X`; + } + /** * Inserts `x` lines at cursor position. Shifting current line and below * down. Cursor position does not change. Characters that exit the display @@ -89,57 +109,72 @@ export class Ansi { static insertLines(x = 1): string { return `\x1b[${x}L`; } + /** * Deletes `x` lines at cursor position. Shifting below lines up. */ static deleteLines(x = 1): string { return `\x1b[${x}M`; } - /** - * Deletes `x` characters at cursor position and to the right. Shifting line - * content left. - */ - static deleteCharacters(x = 1): string { - return `\x1b[${x}P`; - } + /** * Moves cursor position up `x` lines or up to the top margin. */ static moveCursorUp(x = 1): string { return `\x1b[${x}A`; } + + /** + * Moves cursor position `x` lines up or up to the top of the margin, and to + * the beginning of that line. + */ + static moveCursorUpStart(x = 1): string { + return `\x1b[${x}F`; + } + /** * Moves cursor position down `x` lines or up to the bottom margin. */ static moveCursorDown(x = 1): string { return `\x1b[${x}B`; } + + /** + * Moves cursor position `x` lines down or up to the bottom margin, and to + * the beginning of that line. + */ + static moveCursorDownStart(x = 1): string { + return `\x1b[${x}E`; + } + /** * Moves cursor position `x` columns right or up to the right margin. */ static moveCursorRight(x = 1): string { return `\x1b[${x}C`; } + /** - * Moves cursor position `x` columns left or up to the left margin. + * Moves cursor position `x` tab stops right or up to the right margin. */ - static moveCursorLeft(x = 1): string { - return `\x1b[${x}D`; + static moveCursorRightTab(x = 1): string { + return `\x1b[${x}I`; } + /** - * Moves cursor position `x` lines down or up to the bottom margin, and to - * the beginning of that line. + * Moves cursor position `x` columns left or up to the left margin. */ - static moveCursorDownStart(x = 1): string { - return `\x1b[${x}E`; + static moveCursorLeft(x = 1): string { + return `\x1b[${x}D`; } + /** - * Moves cursor position `x` lines up or up to the top of the margin, and to - * the beginning of that line. + * Moves cursor position `x` tab stops left or up to the left margin. */ - static moveCursorUpStart(x = 1): string { - return `\x1b[${x}F`; + static moveCursorLeftTab(x = 1): string { + return `\x1b[${x}Z`; } + /** * Sets cursor position to column `x` or up to the sides of the margins. * Columns begin at `1` not `0`. @@ -147,6 +182,7 @@ export class Ansi { static setCursorColumn(x = 1): string { return `\x1b[${x}G`; } + /** * Sets cursor position to line `x` or down to the bottom of the margin. * Lines begin at `1` not `0`. @@ -154,6 +190,7 @@ export class Ansi { static setCursorLine(x = 1): string { return `\x1b[${x}d`; } + /** * Sets cursor position to `x` line and `y` column or up to the margin. Lines * and columns begin at `1` not `0`. @@ -161,18 +198,28 @@ export class Ansi { static setCursorPosition(x = 1, y = 1): string { return `\x1b[${x};${y}H`; } + /** - * Moves cursor position `x` tab stops right or up to the right margin. + * Erases line content to the right of cursor position. */ - static moveCursorRightTab(x = 1): string { - return `\x1b[${x}I`; + static get eraseLineAfterCursor(): string { + return "\x1b[0K"; } + /** - * Moves cursor position `x` tab stops left or up to the left margin. + * Erases line content to the left of cursor position. */ - static moveCursorLeftTab(x = 1): string { - return `\x1b[${x}Z`; + static get eraseLineBeforeCursor(): string { + return "\x1b[1K"; } + + /** + * Erases entire line content. + */ + static get eraseLine(): string { + return "\x1b[2K"; + } + /** * Erases content of lines below cursor position and content to the right on * the same line as cursor. @@ -180,6 +227,7 @@ export class Ansi { static get eraseDisplayAfterCursor(): string { return "\x1b[0J"; } + /** * Erases content of lines above cursor position and content to the left on * the same line as cursor. @@ -187,36 +235,14 @@ export class Ansi { static get eraseDisplayBeforeCursor(): string { return "\x1b[1J"; } + /** * Erases all content. */ static get eraseDisplay(): string { return "\x1b[2J"; } - /** - * Erases line content to the right of cursor position. - */ - static get eraseLineAfterCursor(): string { - return "\x1b[0K"; - } - /** - * Erases line content to the left of cursor position. - */ - static get eraseLineBeforeCursor(): string { - return "\x1b[1K"; - } - /** - * Erases entire line content. - */ - static get eraseLine(): string { - return "\x1b[2K"; - } - /** - * Erases `x` characters at cursor position and to the right. - */ - static eraseCharacters(x = 1): string { - return `\x1b[${x}X`; - } + /** * Shifts content within the scrollable region up `x` lines, inserting blank * lines at the bottom of the scrollable region. @@ -224,6 +250,7 @@ export class Ansi { static shiftUpAndInsert(x = 1): string { return `\x1b[${x}S`; } + /** * Shifts content within the scrollable region down `x` lines, inserting * blank lines at the top of the scrollable region. @@ -231,12 +258,14 @@ export class Ansi { static shiftDownAndInsert(x = 1): string { return `\x1b[${x}T`; } + /** * Repeats last graphic character printed `x` times at cursor position. */ static repeatLastCharacter(x = 1): string { return `\x1b[${x}b`; } + /** * Causes existing characters to the right of the cursor position to shift * right as new characters are written. Opposite of @@ -245,6 +274,7 @@ export class Ansi { static get insertMode(): string { return "\x1b[4h"; } + /** * Causes existing characters to be overwritten at the cursor position by new * characters. See also {@linkcode Ansi.insertMode}. @@ -252,6 +282,7 @@ export class Ansi { static get replaceMode(): string { return "\x1b[4l"; } + /** * Causes top and bottom margins to shrink to scrollable region (See * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving @@ -260,6 +291,7 @@ export class Ansi { static get enableOriginMode(): string { return "\x1b[?6h"; } + /** * Causes the top and bottom margins to enlarge to the user's display. See * {@linkcode Ansi.enableOriginMode}. @@ -267,6 +299,7 @@ export class Ansi { static get disableOriginMode(): string { return "\x1b[?6l"; } + /** * Causes cursor to automatically move to the next line when it hits the * end of the current line to continue writing. See also @@ -275,6 +308,7 @@ export class Ansi { static get enableAutoWrap(): string { return "\x1b[?7h"; } + /** * Causes cursor to remain on the same line when it hits the end of the * current line. See also {@linkcode Ansi.enableAutoWrap}. @@ -282,12 +316,14 @@ export class Ansi { static get disableAutoWrap(): string { return "\x1b[?7l"; } + /** * Sets the cursor animation style. */ static setCursorStyle(x: CursorStyle): string { return `\x1b[${x} q`; } + /** * Causes cursor position to be visible to the user. See also * {@linkcode Ansi.hideCursor}. @@ -295,6 +331,7 @@ export class Ansi { static get showCursor(): string { return "\x1b[?25h"; } + /** * Causes cursor position to be hidden from the user. See also * {@linkcode Ansi.showCursor}. @@ -302,6 +339,7 @@ export class Ansi { static get hideCursor(): string { return "\x1b[?25l"; } + /** * Sets the scrollable region of the display. Allowing either or both the top * and bottom lines to not have their content moved when the scrolling region From 3df59884a501e245e2a9c29c45ad4ce7824d6794 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:15:26 +1000 Subject: [PATCH 04/25] include default setting for cursor style --- cli/unstable_ansi.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index e962bfdccad7..a31c437a161c 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -353,6 +353,7 @@ export class Ansi { } export const enum CursorStyle { + Default = 0, BlinkingBlock = 1, SteadyBlock = 2, BlinkingUnderline = 3, From d8fe8907115964a8f132223cc6e73e1135224aec Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 13:27:43 +1000 Subject: [PATCH 05/25] fix method to omit instead of calc number --- cli/unstable_ansi.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index a31c437a161c..1da1dd7fbff4 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -347,8 +347,7 @@ export class Ansi { * bottom line of the scrollable region. */ static setScrollableRegion(x = 1, y?: number): string { - y ??= Deno.consoleSize().rows; - return `\x1b[${x};${y}r`; + return `\x1b[${x}${y == undefined ? "" : `;${y}`}r`; } } From 9a33735659de69047cf22887116b70a71c4515db Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:28:12 +1000 Subject: [PATCH 06/25] add a million examples... --- cli/unstable_ansi.ts | 530 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 525 insertions(+), 5 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index 1da1dd7fbff4..d19174c8c815 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -1,14 +1,39 @@ // Copyright 2018-2025 the Deno authors. MIT license. -// https://invisible-island.net/xterm/ctlseqs/ctlseqs.html -// TODO: CSI Ps n - +/** + * Ansi is a class with static methods and properties that returns various Ansi + * Escape Sequences. This class is not an exhaustive list of what is possible + * with Ansi Escape Sequences, nor does it guarentee that every code will work + * in every terminal. The only way to guarentee that only one code will work in + * a particular terminal, is to check for yourself. Calling these methods and + * properties does not automatically change the terminal settings. Only once + * they are passed to stdout or stderr will they take effect. + * + * These codes were based off the + * [xterm reference](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). + * + * @example Basic Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * ``` + */ export class Ansi { /** * Causes content on the current line to enlarge, showing only the top half * of characters with each character taking up two columns. Can be used in * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to * make text appear twice as big. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * ``` */ static get doubleHeightTop(): string { return "\x1b#3"; @@ -19,6 +44,14 @@ export class Ansi { * half of the characters with each character taking up two columns. Can be * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous * line to make text appear twice as big. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * ``` */ static get doubleHeightBottom(): string { return "\x1b#4"; @@ -26,7 +59,23 @@ export class Ansi { /** * Causes content on the current line to shrink down to a single column, - * essentally reverting the effects of {@linkcode Ansi.doubleHeightTop}, {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. + * essentally reverting the effects of {@linkcode Ansi.doubleHeightTop}, + * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * Ansi.deleteLines(1) + + * Ansi.singleWidth, + * ); + * ``` */ static get singleWidth(): string { return "\x1b#5"; @@ -34,7 +83,14 @@ export class Ansi { /** * Causes content on the current line to stretch out, with each character - * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth} + * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleWidth + "Hello World!"); + * ``` */ static get doubleWidth(): string { return "\x1b#6"; @@ -43,6 +99,19 @@ export class Ansi { /** * Saves current cursor position that can later be restored with * {@linkcode Ansi.restoreCursorPosition}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.saveCursorPosition + + * Ansi.setCursorPosition(Deno.consoleSize().rows, 1) + + * Ansi.eraseLine + + * "Hello World!" + + * Ansi.restoreCursorPosition, + * ); + * ``` */ static get saveCursorPosition(): string { return "\x1b7"; @@ -51,6 +120,19 @@ export class Ansi { /** * Restores cursor position that was earlier saved with * {@linkcode Ansi.saveCursorPosition}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.saveCursorPosition + + * Ansi.setCursorPosition(Deno.consoleSize().rows) + + * Ansi.eraseLine + + * "Hello World!" + + * Ansi.restoreCursorPosition, + * ); + * ``` */ static get restoreCursorPosition(): string { return "\x1b8"; @@ -62,6 +144,16 @@ export class Ansi { * sets and more. Essentally making the terminal behave as if it were just * started by the user. This command is very disruptive to the user. Also see * {@linkcode Ansi.softReset}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.hardReset); + * ``` */ static get hardReset(): string { return "\x1bc"; @@ -72,6 +164,16 @@ export class Ansi { * reinitalising the terminal like {@linkcode Ansi.hardReset}. It preserves * things like cursor position and display content, but clears modes, * character sets, etc. Should probably be called when exiting the program. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.softReset); + * ``` */ static get softReset(): string { return "\x1b[!p"; @@ -81,6 +183,20 @@ export class Ansi { * Inserts `x` spaces at the cursor position. Shifting existing line content * to the right. Cursor position does not change. Characters that exit the * display are discarded. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(6) + + * Ansi.insertSpace(10), + * ); + * ``` */ static insertSpace(x = 1): string { return `\x1b[${x}@`; @@ -89,6 +205,20 @@ export class Ansi { /** * Deletes `x` characters at cursor position and to the right. Shifting line * content left. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart() + + * Ansi.deleteCharacters(5) + + * "Bye", + * ); + * ``` */ static deleteCharacters(x = 1): string { return `\x1b[${x}P`; @@ -96,6 +226,21 @@ export class Ansi { /** * Erases `x` characters at cursor position and to the right. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseCharacters(6) + + * "Bob!", + * ); + * ``` */ static eraseCharacters(x = 1): string { return `\x1b[${x}X`; @@ -105,6 +250,20 @@ export class Ansi { * Inserts `x` lines at cursor position. Shifting current line and below * down. Cursor position does not change. Characters that exit the display * are discarded. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart() + + * Ansi.insertLines() + + * "and Goodbye", + * ); + * ``` */ static insertLines(x = 1): string { return `\x1b[${x}L`; @@ -112,6 +271,18 @@ export class Ansi { /** * Deletes `x` lines at cursor position. Shifting below lines up. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUpStart() + Ansi.deleteLines()); + * await delay(1000); + * console.log("and Goodbye!"); + * ``` */ static deleteLines(x = 1): string { return `\x1b[${x}M`; @@ -119,6 +290,16 @@ export class Ansi { /** * Moves cursor position up `x` lines or up to the top margin. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUp(2) + "Goodbye"); + * ``` */ static moveCursorUp(x = 1): string { return `\x1b[${x}A`; @@ -127,6 +308,16 @@ export class Ansi { /** * Moves cursor position `x` lines up or up to the top of the margin, and to * the beginning of that line. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUpStart(2) + "Goodbye"); + * ``` */ static moveCursorUpStart(x = 1): string { return `\x1b[${x}F`; @@ -134,6 +325,23 @@ export class Ansi { /** * Moves cursor position down `x` lines or up to the bottom margin. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * "Goodbye" + + * Ansi.moveCursorDown() + + * Ansi.setCursorColumn() + + * Ansi.eraseLine + + * "Bob!", + * ); + * ``` */ static moveCursorDown(x = 1): string { return `\x1b[${x}B`; @@ -142,6 +350,22 @@ export class Ansi { /** * Moves cursor position `x` lines down or up to the bottom margin, and to * the beginning of that line. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * "Goodbye" + + * Ansi.moveCursorDownStart() + + * Ansi.eraseLine + + * "Bob!", + * ); + * ``` */ static moveCursorDownStart(x = 1): string { return `\x1b[${x}E`; @@ -149,6 +373,13 @@ export class Ansi { /** * Moves cursor position `x` columns right or up to the right margin. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.moveCursorRight(2) + "Hello World!"); + * ``` */ static moveCursorRight(x = 1): string { return `\x1b[${x}C`; @@ -156,6 +387,13 @@ export class Ansi { /** * Moves cursor position `x` tab stops right or up to the right margin. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.moveCursorRightTab() + "Hello World!"); + * ``` */ static moveCursorRightTab(x = 1): string { return `\x1b[${x}I`; @@ -163,6 +401,17 @@ export class Ansi { /** * Moves cursor position `x` columns left or up to the left margin. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.moveCursorRight(4) + + * Ansi.moveCursorLeft(2) + + * "Hello World!", + * ); + * ``` */ static moveCursorLeft(x = 1): string { return `\x1b[${x}D`; @@ -170,6 +419,16 @@ export class Ansi { /** * Moves cursor position `x` tab stops left or up to the left margin. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.moveCursorRightTab(2) + + * Ansi.moveCursorLeftTab() + + * "Hello World!", + * ); */ static moveCursorLeftTab(x = 1): string { return `\x1b[${x}Z`; @@ -178,6 +437,20 @@ export class Ansi { /** * Sets cursor position to column `x` or up to the sides of the margins. * Columns begin at `1` not `0`. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye!", + * ); + * ``` */ static setCursorColumn(x = 1): string { return `\x1b[${x}G`; @@ -186,6 +459,13 @@ export class Ansi { /** * Sets cursor position to line `x` or down to the bottom of the margin. * Lines begin at `1` not `0`. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.setCursorLine() + Ansi.eraseLine + "Hello World!"); + * ``` */ static setCursorLine(x = 1): string { return `\x1b[${x}d`; @@ -194,6 +474,17 @@ export class Ansi { /** * Sets cursor position to `x` line and `y` column or up to the margin. Lines * and columns begin at `1` not `0`. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.setCursorPosition(5, 2) + + * Ansi.eraseLine + + * "Hello World!", + * ); + * ``` */ static setCursorPosition(x = 1, y = 1): string { return `\x1b[${x};${y}H`; @@ -201,6 +492,20 @@ export class Ansi { /** * Erases line content to the right of cursor position. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseLineAfterCursor, + * ); + * ``` */ static get eraseLineAfterCursor(): string { return "\x1b[0K"; @@ -208,6 +513,20 @@ export class Ansi { /** * Erases line content to the left of cursor position. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseLineBeforeCursor, + * ); + * ``` */ static get eraseLineBeforeCursor(): string { return "\x1b[1K"; @@ -215,6 +534,16 @@ export class Ansi { /** * Erases entire line content. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log(Ansi.moveCursorUp() + Ansi.eraseLine); + * ``` */ static get eraseLine(): string { return "\x1b[2K"; @@ -223,6 +552,20 @@ export class Ansi { /** * Erases content of lines below cursor position and content to the right on * the same line as cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseDisplayAfterCursor, + * ); + * ``` */ static get eraseDisplayAfterCursor(): string { return "\x1b[0J"; @@ -231,6 +574,20 @@ export class Ansi { /** * Erases content of lines above cursor position and content to the left on * the same line as cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseDisplayBeforeCursor, + * ); + * ``` */ static get eraseDisplayBeforeCursor(): string { return "\x1b[1J"; @@ -238,6 +595,16 @@ export class Ansi { /** * Erases all content. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log(Ansi.eraseDisplay); + * ``` */ static get eraseDisplay(): string { return "\x1b[2J"; @@ -246,6 +613,13 @@ export class Ansi { /** * Shifts content within the scrollable region up `x` lines, inserting blank * lines at the bottom of the scrollable region. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.shiftUpAndInsert()); + * ``` */ static shiftUpAndInsert(x = 1): string { return `\x1b[${x}S`; @@ -254,6 +628,13 @@ export class Ansi { /** * Shifts content within the scrollable region down `x` lines, inserting * blank lines at the top of the scrollable region. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.shiftDownAndInsert(3)); + * ``` */ static shiftDownAndInsert(x = 1): string { return `\x1b[${x}T`; @@ -261,6 +642,13 @@ export class Ansi { /** * Repeats last graphic character printed `x` times at cursor position. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!" + Ansi.repeatLastCharacter(4)); + * ``` */ static repeatLastCharacter(x = 1): string { return `\x1b[${x}b`; @@ -270,6 +658,22 @@ export class Ansi { * Causes existing characters to the right of the cursor position to shift * right as new characters are written. Opposite of * {@linkcode Ansi.replaceMode}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.insertMode + + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye " + + * Ansi.replaceMode, + * ); + * ``` */ static get insertMode(): string { return "\x1b[4h"; @@ -278,6 +682,22 @@ export class Ansi { /** * Causes existing characters to be overwritten at the cursor position by new * characters. See also {@linkcode Ansi.insertMode}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.insertMode + + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye " + + * Ansi.replaceMode, + * ); + * ``` */ static get replaceMode(): string { return "\x1b[4l"; @@ -287,6 +707,22 @@ export class Ansi { * Causes top and bottom margins to shrink to scrollable region (See * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving * to the lines outside it. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setCursorPosition() + + * "Hello World" + + * Ansi.setScrollableRegion(2) + + * Ansi.enableOriginMode, + * ); + * await delay(1000); + * console.log(Ansi.setCursorPosition() + "Bye World!"); + * ``` */ static get enableOriginMode(): string { return "\x1b[?6h"; @@ -295,6 +731,29 @@ export class Ansi { /** * Causes the top and bottom margins to enlarge to the user's display. See * {@linkcode Ansi.enableOriginMode}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setCursorPosition() + + * "Hello World" + + * Ansi.setScrollableRegion(2) + + * Ansi.enableOriginMode, + * ); + * await delay(1000); + * console.log(Ansi.setCursorPosition() + "Bye World!"); + * await delay(1000); + * console.log( + * Ansi.disableOriginMode + + * Ansi.setCursorPosition() + + * Ansi.eraseLine + + * "Hi World!", + * ); + * ``` */ static get disableOriginMode(): string { return "\x1b[?6l"; @@ -304,6 +763,13 @@ export class Ansi { * Causes cursor to automatically move to the next line when it hits the * end of the current line to continue writing. See also * {@linkcode Ansi.disableAutoWrap}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.enableAutoWrap + "A" + "h".repeat(500)); + * ``` */ static get enableAutoWrap(): string { return "\x1b[?7h"; @@ -312,6 +778,13 @@ export class Ansi { /** * Causes cursor to remain on the same line when it hits the end of the * current line. See also {@linkcode Ansi.enableAutoWrap}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.disableAutoWrap + "A" + "h".repeat(500)); + * ``` */ static get disableAutoWrap(): string { return "\x1b[?7l"; @@ -319,6 +792,13 @@ export class Ansi { /** * Sets the cursor animation style. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.setCursorStyle(CursorStyle.BlinkingUnderline)); + * ``` */ static setCursorStyle(x: CursorStyle): string { return `\x1b[${x} q`; @@ -327,6 +807,15 @@ export class Ansi { /** * Causes cursor position to be visible to the user. See also * {@linkcode Ansi.hideCursor}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.showCursor); */ static get showCursor(): string { return "\x1b[?25h"; @@ -335,6 +824,15 @@ export class Ansi { /** * Causes cursor position to be hidden from the user. See also * {@linkcode Ansi.showCursor}. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.showCursor); */ static get hideCursor(): string { return "\x1b[?25l"; @@ -345,12 +843,34 @@ export class Ansi { * and bottom lines to not have their content moved when the scrolling region * is updated. `x` is the top line of the scrollable region. `y` is the * bottom line of the scrollable region. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setScrollableRegion(3, 10), + * ); + * setInterval(() => console.log(Math.random()), 1000); + * ``` */ static setScrollableRegion(x = 1, y?: number): string { return `\x1b[${x}${y == undefined ? "" : `;${y}`}r`; } } +/** + * CurorStyle is a const enum used to set the value in + * {@linkcode Ansi.setCursorStyle}. + * + * @example Usage + * ```ts ignore + * import { Ansi } from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.setCursorStyle(CursorStyle.BlinkingUnderline)); + * ``` + */ export const enum CursorStyle { Default = 0, BlinkingBlock = 1, From 6882b322ce725c6a57493e81f48de7ac4e438068 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:30:19 +1000 Subject: [PATCH 07/25] add export --- cli/deno.json | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/deno.json b/cli/deno.json index 722276e6ec35..bd336083b2d5 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -5,6 +5,7 @@ ".": "./mod.ts", "./parse-args": "./parse_args.ts", "./prompt-secret": "./prompt_secret.ts", + "./unstable-ansi": "./unstable_ansi.ts", "./unstable-progress-bar": "./unstable_progress_bar.ts", "./unstable-progress-bar-stream": "./unstable_progress_bar_stream.ts", "./unstable-prompt-select": "./unstable_prompt_select.ts", From 7c94569dbfabe7bb170c865a8cb40a6d2a3dc3a9 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:30:27 +1000 Subject: [PATCH 08/25] fix spelling --- cli/unstable_ansi.ts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index d19174c8c815..a550b1436cb8 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -3,8 +3,8 @@ /** * Ansi is a class with static methods and properties that returns various Ansi * Escape Sequences. This class is not an exhaustive list of what is possible - * with Ansi Escape Sequences, nor does it guarentee that every code will work - * in every terminal. The only way to guarentee that only one code will work in + * with Ansi Escape Sequences, nor does it guarantee that every code will work + * in every terminal. The only way to guarantee that only one code will work in * a particular terminal, is to check for yourself. Calling these methods and * properties does not automatically change the terminal settings. Only once * they are passed to stdout or stderr will they take effect. @@ -59,7 +59,7 @@ export class Ansi { /** * Causes content on the current line to shrink down to a single column, - * essentally reverting the effects of {@linkcode Ansi.doubleHeightTop}, + * essentially reverting the effects of {@linkcode Ansi.doubleHeightTop}, * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. * * @example Usage @@ -141,7 +141,7 @@ export class Ansi { /** * This is a full reset of the terminal, reverting it back to its original * default settings, clearing the screen, resetting modes, colors, character - * sets and more. Essentally making the terminal behave as if it were just + * sets and more. Essentially making the terminal behave as if it were just * started by the user. This command is very disruptive to the user. Also see * {@linkcode Ansi.softReset}. * @@ -160,8 +160,8 @@ export class Ansi { } /** - * This command resets many settings to their inital state without fully - * reinitalising the terminal like {@linkcode Ansi.hardReset}. It preserves + * This command resets many settings to their initial state without fully + * reinitialising the terminal like {@linkcode Ansi.hardReset}. It preserves * things like cursor position and display content, but clears modes, * character sets, etc. Should probably be called when exiting the program. * @@ -861,7 +861,7 @@ export class Ansi { } /** - * CurorStyle is a const enum used to set the value in + * CursorStyle is a const enum used to set the value in * {@linkcode Ansi.setCursorStyle}. * * @example Usage From 7aa82151ddb81571a89fa055cb4e57f0b134e210 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 8 Jul 2025 14:49:36 +1000 Subject: [PATCH 09/25] fix lint errors by adding missing jsdocs --- cli/unstable_ansi.ts | 123 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 122 insertions(+), 1 deletion(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index a550b1436cb8..7719979c8b36 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -27,6 +27,8 @@ export class Ansi { * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to * make text appear twice as big. * + * @returns string The ANSI escape code for double-height top. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -45,6 +47,8 @@ export class Ansi { * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous * line to make text appear twice as big. * + * @returns string The ANSI escape code for double-height bottom. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -62,6 +66,8 @@ export class Ansi { * essentially reverting the effects of {@linkcode Ansi.doubleHeightTop}, * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. * + * @returns string The ANSI escape code for single-width. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -85,6 +91,8 @@ export class Ansi { * Causes content on the current line to stretch out, with each character * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth}. * + * @returns string The ANSI escape code for double-width. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -100,6 +108,8 @@ export class Ansi { * Saves current cursor position that can later be restored with * {@linkcode Ansi.restoreCursorPosition}. * + * @returns string The ANSI escape code for saving cursor position. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -121,6 +131,8 @@ export class Ansi { * Restores cursor position that was earlier saved with * {@linkcode Ansi.saveCursorPosition}. * + * @returns string The ANSI escape code for restoring cursor position. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -145,6 +157,8 @@ export class Ansi { * started by the user. This command is very disruptive to the user. Also see * {@linkcode Ansi.softReset}. * + * @returns string The ANSI escape code for hard resetting the terminal. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -161,10 +175,12 @@ export class Ansi { /** * This command resets many settings to their initial state without fully - * reinitialising the terminal like {@linkcode Ansi.hardReset}. It preserves + * reinitializing the terminal like {@linkcode Ansi.hardReset}. It preserves * things like cursor position and display content, but clears modes, * character sets, etc. Should probably be called when exiting the program. * + * @returns string The ANSI escape code for soft resetting the terminal. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -184,6 +200,9 @@ export class Ansi { * to the right. Cursor position does not change. Characters that exit the * display are discarded. * + * @param x The number of spaces to insert. + * @returns string The ANSI escape code for inserting spaces. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -206,6 +225,9 @@ export class Ansi { * Deletes `x` characters at cursor position and to the right. Shifting line * content left. * + * @param x The number of characters to delete. + * @returns string The ANSI escape code for deleting characters. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -227,6 +249,9 @@ export class Ansi { /** * Erases `x` characters at cursor position and to the right. * + * @param x The number of characters to erase. + * @returns string The ANSI escape code for erasing characters. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -251,6 +276,9 @@ export class Ansi { * down. Cursor position does not change. Characters that exit the display * are discarded. * + * @param x The number of lines to insert. + * @returns string The ANSI escape code for inserting lines. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -272,6 +300,9 @@ export class Ansi { /** * Deletes `x` lines at cursor position. Shifting below lines up. * + * @param x The number of lines to delete. + * @returns string The ANSI escape code for deleting lines. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -291,6 +322,9 @@ export class Ansi { /** * Moves cursor position up `x` lines or up to the top margin. * + * @param x The number of lines to move up. + * @returns string The ANSI escape code for moving the cursor up. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -309,6 +343,10 @@ export class Ansi { * Moves cursor position `x` lines up or up to the top of the margin, and to * the beginning of that line. * + * @param x The number of lines to move up. + * @returns string The ANSI escape code for moving the cursor up and to the + * beginning of the line. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -326,6 +364,9 @@ export class Ansi { /** * Moves cursor position down `x` lines or up to the bottom margin. * + * @param x The number of lines to move down. + * @returns string The ANSI escape code for moving the cursor down. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -351,6 +392,10 @@ export class Ansi { * Moves cursor position `x` lines down or up to the bottom margin, and to * the beginning of that line. * + * @param x The number of lines to move down. + * @returns string The ANSI escape code for moving the cursor down and to the + * beginning of the line. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -374,6 +419,9 @@ export class Ansi { /** * Moves cursor position `x` columns right or up to the right margin. * + * @param x The number of columns to move right. + * @returns string The ANSI escape code for moving the cursor right. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -388,6 +436,10 @@ export class Ansi { /** * Moves cursor position `x` tab stops right or up to the right margin. * + * @param x The number of tab stops to move right. + * @returns string The ANSI escape code for moving the cursor right every tab + * stop. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -402,6 +454,9 @@ export class Ansi { /** * Moves cursor position `x` columns left or up to the left margin. * + * @param x The number of columns to move left. + * @returns string The ANSI escape code for moving the cursor left. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -420,6 +475,10 @@ export class Ansi { /** * Moves cursor position `x` tab stops left or up to the left margin. * + * @param x The number of tab stops to move left. + * @returns string The ANSI escape code for moving the cursor left every tab + * stop. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -429,6 +488,7 @@ export class Ansi { * Ansi.moveCursorLeftTab() + * "Hello World!", * ); + * ``` */ static moveCursorLeftTab(x = 1): string { return `\x1b[${x}Z`; @@ -438,6 +498,9 @@ export class Ansi { * Sets cursor position to column `x` or up to the sides of the margins. * Columns begin at `1` not `0`. * + * @param x The column to move to. + * @returns string The ANSI escape code for setting the cursor column. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -460,6 +523,9 @@ export class Ansi { * Sets cursor position to line `x` or down to the bottom of the margin. * Lines begin at `1` not `0`. * + * @param x The line to move to. + * @returns string The ANSI escape code for setting the cursor line. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -475,6 +541,10 @@ export class Ansi { * Sets cursor position to `x` line and `y` column or up to the margin. Lines * and columns begin at `1` not `0`. * + * @param x The line to move to. + * @param y The column to move to. + * @returns string The ANSI escape code for setting the cursor position. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -493,6 +563,9 @@ export class Ansi { /** * Erases line content to the right of cursor position. * + * @returns string The ANSI escape code for erasing the line content to the + * right of the cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -514,6 +587,9 @@ export class Ansi { /** * Erases line content to the left of cursor position. * + * @returns string The ANSI escape code for erasing the line content to the + * left of the cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -535,6 +611,8 @@ export class Ansi { /** * Erases entire line content. * + * @returns string The ANSI escape code for erasing the entire line content. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -553,6 +631,9 @@ export class Ansi { * Erases content of lines below cursor position and content to the right on * the same line as cursor. * + * @returns string The ANSI escape code for erasing the content after the + * cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -575,6 +656,9 @@ export class Ansi { * Erases content of lines above cursor position and content to the left on * the same line as cursor. * + * @returns string The ANSI escape code for erasing the content before the + * cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -596,6 +680,8 @@ export class Ansi { /** * Erases all content. * + * @returns string The ANSI escape code for erasing the entire display. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -614,6 +700,9 @@ export class Ansi { * Shifts content within the scrollable region up `x` lines, inserting blank * lines at the bottom of the scrollable region. * + * @param x The number of lines content should be shifted up. + * @returns string The ANSI escape code for shifting content up. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -629,6 +718,9 @@ export class Ansi { * Shifts content within the scrollable region down `x` lines, inserting * blank lines at the top of the scrollable region. * + * @param x The number of lines content should be shifted down. + * @returns string The ANSI escape code for shifting content down. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -643,6 +735,10 @@ export class Ansi { /** * Repeats last graphic character printed `x` times at cursor position. * + * @param x The number of times the last character printed should be repeated. + * @returns string The ANSI escape code for repeating the last printed + * character. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -659,6 +755,8 @@ export class Ansi { * right as new characters are written. Opposite of * {@linkcode Ansi.replaceMode}. * + * @returns string The ANSI escape code for entering insert mode. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -683,6 +781,8 @@ export class Ansi { * Causes existing characters to be overwritten at the cursor position by new * characters. See also {@linkcode Ansi.insertMode}. * + * @returns string The ANSI escape code for entering replace mode. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -708,6 +808,8 @@ export class Ansi { * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving * to the lines outside it. * + * @returns string The ANSI escape code for enabling origin mode. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -732,6 +834,8 @@ export class Ansi { * Causes the top and bottom margins to enlarge to the user's display. See * {@linkcode Ansi.enableOriginMode}. * + * @returns string The ANSI escape code for disabling origin mode. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -764,6 +868,8 @@ export class Ansi { * end of the current line to continue writing. See also * {@linkcode Ansi.disableAutoWrap}. * + * @returns string The ANSI escape code to enable auto-wrap. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -779,6 +885,8 @@ export class Ansi { * Causes cursor to remain on the same line when it hits the end of the * current line. See also {@linkcode Ansi.enableAutoWrap}. * + * @returns string The ANSI escape code to disable auto-wrap. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -793,6 +901,9 @@ export class Ansi { /** * Sets the cursor animation style. * + * @param x The cursor style to set. + * @returns string The ANSI escape code to set the cursor style. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; @@ -808,6 +919,8 @@ export class Ansi { * Causes cursor position to be visible to the user. See also * {@linkcode Ansi.hideCursor}. * + * @returns string The ANSI escape code to show the cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -816,6 +929,7 @@ export class Ansi { * console.log(Ansi.hideCursor); * await delay(5000); * console.log(Ansi.showCursor); + * ``` */ static get showCursor(): string { return "\x1b[?25h"; @@ -825,6 +939,8 @@ export class Ansi { * Causes cursor position to be hidden from the user. See also * {@linkcode Ansi.showCursor}. * + * @returns string The ANSI escape code to hide the cursor. + * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; @@ -833,6 +949,7 @@ export class Ansi { * console.log(Ansi.hideCursor); * await delay(5000); * console.log(Ansi.showCursor); + * ``` */ static get hideCursor(): string { return "\x1b[?25l"; @@ -844,6 +961,10 @@ export class Ansi { * is updated. `x` is the top line of the scrollable region. `y` is the * bottom line of the scrollable region. * + * @param x The top line of the scrollable region. + * @param y The bottom line of the scrollable region. + * @returns string The ANSI escape code to set the scrollable region. + * * @example Usage * ```ts ignore * import { Ansi } from "@std/cli/unstable_ansi"; From a610eaf36d714dab821d855e15fe43681d825677 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Wed, 9 Jul 2025 19:49:48 +1000 Subject: [PATCH 10/25] feat(cli): StaticLine --- cli/deno.json | 1 + cli/unstable_static_line.ts | 155 ++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 cli/unstable_static_line.ts diff --git a/cli/deno.json b/cli/deno.json index bd336083b2d5..a1b600fc0a13 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -11,6 +11,7 @@ "./unstable-prompt-select": "./unstable_prompt_select.ts", "./unstable-prompt-multiple-select": "./unstable_prompt_multiple_select.ts", "./unstable-spinner": "./unstable_spinner.ts", + "./unstable-static-line": "./unstable_static_line.ts", "./unicode-width": "./unicode_width.ts" } } diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts new file mode 100644 index 000000000000..31f6becf144c --- /dev/null +++ b/cli/unstable_static_line.ts @@ -0,0 +1,155 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +import { Ansi } from "./unstable_ansi.ts"; + +let nextID = 0; +const linesAtTop: number[] = []; +const linesAtBottom: number[] = []; + +const getRows = "Deno" in globalThis + // deno-lint-ignore no-explicit-any + ? (): number => (globalThis as any).Deno.consoleSize().rows + // deno-lint-ignore no-explicit-any + : (): number => (globalThis as any).process.stderr.rows; +const write = "Deno" in globalThis + ? (() => { + const encoder = new TextEncoder(); + // deno-lint-ignore no-explicit-any + return (x: string) => (globalThis as any).stderr.write(encoder.encode(x)); + })() + // deno-lint-ignore no-explicit-any + : (x: string) => (globalThis as any).process.stderr.write(x); + +/** + * StaticLine is a class that assigns a line in the terminal for you to write + * to and that won't be overwritten by `console.log`. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ +export class StaticLine { + #id = ++nextID; + #atTop: boolean; + #lines: number[]; + #released = false; + /** + * Constructs a new instance. + * + * @param atTop Whether the line should be at the top or bottom of the + * terminal. + */ + constructor(atTop = false) { + this.#atTop = atTop; + this.#lines = atTop ? linesAtTop : linesAtBottom; + this.#lines.push(this.#id); + const top = linesAtTop.length + 1; + const bottom = getRows() - linesAtBottom.length; + write( + (atTop ? "" : Ansi.shiftUpAndInsert()) + + Ansi.setScrollableRegion(top, bottom) + + Ansi.setCursorPosition(bottom), + ); + } + + /** + * Overwrites the contents of the line. + * + * @param line The new content to write. + * @returns A promise that resolves when the line is written. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ + async write(line: string): Promise { + if (this.#released) throw new ReferenceError("Line has been released"); + await write( + Ansi.saveCursorPosition + + Ansi.disableAutoWrap + + Ansi.setCursorPosition( + this.#atTop + ? linesAtTop.indexOf(this.#id) + 1 + : getRows() - linesAtBottom.indexOf(this.#id), + ) + + Ansi.eraseLine + + line + + Ansi.enableAutoWrap + + Ansi.restoreCursorPosition, + ); + } + + /** + * Releases the line so other content can use it. + * + * @returns A promise that resolves when the line is released. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ + async releaseLine(): Promise { + if (this.#released) return; + this.#released = true; + const index = this.#lines.indexOf(this.#id); + this.#lines.splice(index, 1); + const rows = getRows(); + const top = linesAtTop.length + 1; + const bottom = rows - linesAtBottom.length; + await write( + Ansi.saveCursorPosition + + (this.#atTop + ? Ansi.setScrollableRegion(index + 1, top + 1) + + Ansi.shiftUpAndInsert() + : (linesAtBottom.length + ? Ansi.setScrollableRegion( + bottom, + rows - index, + ) + + Ansi.shiftDownAndInsert() + : Ansi.setCursorPosition(rows) + + Ansi.eraseLine)) + + Ansi.setScrollableRegion(top, bottom) + + Ansi.restoreCursorPosition, + ); + } +} From 886b852e0937b86f8ed2a85e384e3c94fd3c1069 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Fri, 11 Jul 2025 19:58:05 +1000 Subject: [PATCH 11/25] convert(cli): Ansi class to separate functions and variables --- cli/unstable_ansi.ts | 1898 +++++++++++++++++++++--------------------- 1 file changed, 928 insertions(+), 970 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index 7719979c8b36..af8399c15df2 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -1,995 +1,953 @@ // Copyright 2018-2025 the Deno authors. MIT license. /** - * Ansi is a class with static methods and properties that returns various Ansi - * Escape Sequences. This class is not an exhaustive list of what is possible - * with Ansi Escape Sequences, nor does it guarantee that every code will work - * in every terminal. The only way to guarantee that only one code will work in - * a particular terminal, is to check for yourself. Calling these methods and - * properties does not automatically change the terminal settings. Only once - * they are passed to stdout or stderr will they take effect. + * Ansi is a module that offers export function s and variables that returns + * various Ansi Escape Sequences. This class is not an exhaustive list of what + * is possible with Ansi Escape Sequences, nor does it guarantee that every + * code will work in every terminal. The only way to guarantee that only one + * code will work in a particular terminal, is to check for yourself. Calling + * these export function s and variables does not automatically change the + * terminal settings. Only once they are passed to stdout or stderr will they + * take effect. * * These codes were based off the * [xterm reference](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html). * * @example Basic Usage * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable_ansi"; * * console.log(Ansi.doubleHeightTop + "Hello World!"); * console.log(Ansi.doubleHeightBottom + "Hello World!"); * ``` + * + * @module + */ + +/** + * Causes content on the current line to enlarge, showing only the top half + * of characters with each character taking up two columns. Can be used in + * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to + * make text appear twice as big. + * + * @returns string The ANSI escape code for double-height top. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * ``` + */ +export const doubleHeightTop = "\x1b#3"; + +/** + * Causes content on the current line to enlarge, showing only the bottom + * half of the characters with each character taking up two columns. Can be + * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous + * line to make text appear twice as big. + * + * @returns string The ANSI escape code for double-height bottom. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * ``` + */ +export const doubleHeightBottom = "\x1b#4"; + +/** + * Causes content on the current line to shrink down to a single column, + * essentially reverting the effects of {@linkcode Ansi.doubleHeightTop}, + * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. + * + * @returns string The ANSI escape code for single-width. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleHeightTop + "Hello World!"); + * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * Ansi.deleteLines(1) + + * Ansi.singleWidth, + * ); + * ``` + */ +export const singleWidth = "\x1b#5"; + +/** + * Causes content on the current line to stretch out, with each character + * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth}. + * + * @returns string The ANSI escape code for double-width. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.doubleWidth + "Hello World!"); + * ``` + */ +export const doubleWidth = "\x1b#6"; + +/** + * Saves current cursor position that can later be restored with + * {@linkcode Ansi.restoreCursorPosition}. + * + * @returns string The ANSI escape code for saving cursor position. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.saveCursorPosition + + * Ansi.setCursorPosition(Deno.consoleSize().rows, 1) + + * Ansi.eraseLine + + * "Hello World!" + + * Ansi.restoreCursorPosition, + * ); + * ``` + */ +export const saveCursorPosition = "\x1b7"; + +/** + * Restores cursor position that was earlier saved with + * {@linkcode Ansi.saveCursorPosition}. + * + * @returns string The ANSI escape code for restoring cursor position. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.saveCursorPosition + + * Ansi.setCursorPosition(Deno.consoleSize().rows) + + * Ansi.eraseLine + + * "Hello World!" + + * Ansi.restoreCursorPosition, + * ); + * ``` + */ +export const restoreCursorPosition = "\x1b8"; + +/** + * This is a full reset of the terminal, reverting it back to its original + * default settings, clearing the screen, resetting modes, colors, character + * sets and more. Essentially making the terminal behave as if it were just + * started by the user. This command is very disruptive to the user. Also see + * {@linkcode Ansi.softReset}. + * + * @returns string The ANSI escape code for hard resetting the terminal. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.hardReset); + * ``` + */ +export const hardReset = "\x1bc"; + +/** + * This command resets many settings to their initial state without fully + * reinitializing the terminal like {@linkcode Ansi.hardReset}. It preserves + * things like cursor position and display content, but clears modes, + * character sets, etc. Should probably be called when exiting the program. + * + * @returns string The ANSI escape code for soft resetting the terminal. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.softReset); + * ``` + */ +export const softReset = "\x1b[!p"; + +/** + * Inserts `x` spaces at the cursor position. Shifting existing line content + * to the right. Cursor position does not change. Characters that exit the + * display are discarded. + * + * @param x The number of spaces to insert. + * @returns string The ANSI escape code for inserting spaces. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(6) + + * Ansi.insertSpace(10), + * ); + * ``` + */ +export function insertSpace(x = 1): string { + return `\x1b[${x}@`; +} + +/** + * Deletes `x` characters at cursor position and to the right. Shifting line + * content left. + * + * @param x The number of characters to delete. + * @returns string The ANSI escape code for deleting characters. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart() + + * Ansi.deleteCharacters(5) + + * "Bye", + * ); + * ``` + */ +export function deleteCharacters(x = 1): string { + return `\x1b[${x}P`; +} + +/** + * Erases `x` characters at cursor position and to the right. + * + * @param x The number of characters to erase. + * @returns string The ANSI escape code for erasing characters. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseCharacters(6) + + * "Bob!", + * ); + * ``` + */ +export function eraseCharacters(x = 1): string { + return `\x1b[${x}X`; +} + +/** + * Inserts `x` lines at cursor position. Shifting current line and below + * down. Cursor position does not change. Characters that exit the display + * are discarded. + * + * @param x The number of lines to insert. + * @returns string The ANSI escape code for inserting lines. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart() + + * Ansi.insertLines() + + * "and Goodbye", + * ); + * ``` + */ +export function insertLines(x = 1): string { + return `\x1b[${x}L`; +} + +/** + * Deletes `x` lines at cursor position. Shifting below lines up. + * + * @param x The number of lines to delete. + * @returns string The ANSI escape code for deleting lines. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUpStart() + Ansi.deleteLines()); + * await delay(1000); + * console.log("and Goodbye!"); + * ``` + */ +export function deleteLines(x = 1): string { + return `\x1b[${x}M`; +} + +/** + * Moves cursor position up `x` lines or up to the top margin. + * + * @param x The number of lines to move up. + * @returns string The ANSI escape code for moving the cursor up. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUp(2) + "Goodbye"); + * ``` + */ +export function moveCursorUp(x = 1): string { + return `\x1b[${x}A`; +} + +/** + * Moves cursor position `x` lines up or up to the top of the margin, and to + * the beginning of that line. + * + * @param x The number of lines to move up. + * @returns string The ANSI escape code for moving the cursor up and to the + * beginning of the line. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log(Ansi.moveCursorUpStart(2) + "Goodbye"); + * ``` + */ +export function moveCursorUpStart(x = 1): string { + return `\x1b[${x}F`; +} + +/** + * Moves cursor position down `x` lines or up to the bottom margin. + * + * @param x The number of lines to move down. + * @returns string The ANSI escape code for moving the cursor down. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * "Goodbye" + + * Ansi.moveCursorDown() + + * Ansi.setCursorColumn() + + * Ansi.eraseLine + + * "Bob!", + * ); + * ``` + */ +export function moveCursorDown(x = 1): string { + return `\x1b[${x}B`; +} + +/** + * Moves cursor position `x` lines down or up to the bottom margin, and to + * the beginning of that line. + * + * @param x The number of lines to move down. + * @returns string The ANSI escape code for moving the cursor down and to the + * beginning of the line. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello\nWorld!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUpStart(2) + + * "Goodbye" + + * Ansi.moveCursorDownStart() + + * Ansi.eraseLine + + * "Bob!", + * ); + * ``` + */ +export function moveCursorDownStart(x = 1): string { + return `\x1b[${x}E`; +} + +/** + * Moves cursor position `x` columns right or up to the right margin. + * + * @param x The number of columns to move right. + * @returns string The ANSI escape code for moving the cursor right. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.moveCursorRight(2) + "Hello World!"); + * ``` + */ +export function moveCursorRight(x = 1): string { + return `\x1b[${x}C`; +} + +/** + * Moves cursor position `x` tab stops right or up to the right margin. + * + * @param x The number of tab stops to move right. + * @returns string The ANSI escape code for moving the cursor right every tab + * stop. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.moveCursorRightTab() + "Hello World!"); + * ``` + */ +export function moveCursorRightTab(x = 1): string { + return `\x1b[${x}I`; +} + +/** + * Moves cursor position `x` columns left or up to the left margin. + * + * @param x The number of columns to move left. + * @returns string The ANSI escape code for moving the cursor left. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.moveCursorRight(4) + + * Ansi.moveCursorLeft(2) + + * "Hello World!", + * ); + * ``` + */ +export function moveCursorLeft(x = 1): string { + return `\x1b[${x}D`; +} + +/** + * Moves cursor position `x` tab stops left or up to the left margin. + * + * @param x The number of tab stops to move left. + * @returns string The ANSI escape code for moving the cursor left every tab + * stop. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.moveCursorRightTab(2) + + * Ansi.moveCursorLeftTab() + + * "Hello World!", + * ); + * ``` + */ +export function moveCursorLeftTab(x = 1): string { + return `\x1b[${x}Z`; +} + +/** + * Sets cursor position to column `x` or up to the sides of the margins. + * Columns begin at `1` not `0`. + * + * @param x The column to move to. + * @returns string The ANSI escape code for setting the cursor column. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye!", + * ); + * ``` + */ +export function setCursorColumn(x = 1): string { + return `\x1b[${x}G`; +} + +/** + * Sets cursor position to line `x` or down to the bottom of the margin. + * Lines begin at `1` not `0`. + * + * @param x The line to move to. + * @returns string The ANSI escape code for setting the cursor line. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.setCursorLine() + Ansi.eraseLine + "Hello World!"); + * ``` + */ +export function setCursorLine(x = 1): string { + return `\x1b[${x}d`; +} + +/** + * Sets cursor position to `x` line and `y` column or up to the margin. Lines + * and columns begin at `1` not `0`. + * + * @param x The line to move to. + * @param y The column to move to. + * @returns string The ANSI escape code for setting the cursor position. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.setCursorPosition(5, 2) + + * Ansi.eraseLine + + * "Hello World!", + * ); + * ``` + */ +export function setCursorPosition(x = 1, y = 1): string { + return `\x1b[${x};${y}H`; +} + +/** + * Erases line content to the right of cursor position. + * + * @returns string The ANSI escape code for erasing the line content to the + * right of the cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseLineAfterCursor, + * ); + * ``` + */ +export const eraseLineAfterCursor = "\x1b[0K"; + +/** + * Erases line content to the left of cursor position. + * + * @returns string The ANSI escape code for erasing the line content to the + * left of the cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseLineBeforeCursor, + * ); + * ``` + */ +export const eraseLineBeforeCursor = "\x1b[1K"; + +/** + * Erases entire line content. + * + * @returns string The ANSI escape code for erasing the entire line content. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log(Ansi.moveCursorUp() + Ansi.eraseLine); + * ``` + */ +export const eraseLine = "\x1b[2K"; + +/** + * Erases content of lines below cursor position and content to the right on + * the same line as cursor. + * + * @returns string The ANSI escape code for erasing the content after the + * cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseDisplayAfterCursor, + * ); + * ``` + */ +export const eraseDisplayAfterCursor = "\x1b[0J"; + +/** + * Erases content of lines above cursor position and content to the left on + * the same line as cursor. + * + * @returns string The ANSI escape code for erasing the content before the + * cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * Ansi.eraseDisplayBeforeCursor, + * ); + * ``` + */ +export const eraseDisplayBeforeCursor = "\x1b[1J"; + +/** + * Erases all content. + * + * @returns string The ANSI escape code for erasing the entire display. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log(Ansi.eraseDisplay); + * ``` + */ +export const eraseDisplay = "\x1b[2J"; + +/** + * Shifts content within the scrollable region up `x` lines, inserting blank + * lines at the bottom of the scrollable region. + * + * @param x The number of lines content should be shifted up. + * @returns string The ANSI escape code for shifting content up. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.shiftUpAndInsert()); + * ``` + */ +export function shiftUpAndInsert(x = 1): string { + return `\x1b[${x}S`; +} + +/** + * Shifts content within the scrollable region down `x` lines, inserting + * blank lines at the top of the scrollable region. + * + * @param x The number of lines content should be shifted down. + * @returns string The ANSI escape code for shifting content down. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.shiftDownAndInsert(3)); + * ``` + */ +export function shiftDownAndInsert(x = 1): string { + return `\x1b[${x}T`; +} + +/** + * Repeats last graphic character printed `x` times at cursor position. + * + * @param x The number of times the last character printed should be repeated. + * @returns string The ANSI escape code for repeating the last printed + * character. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!" + Ansi.repeatLastCharacter(4)); + * ``` + */ +export function repeatLastCharacter(x = 1): string { + return `\x1b[${x}b`; +} + +/** + * Causes existing characters to the right of the cursor position to shift + * right as new characters are written. Opposite of + * {@linkcode Ansi.replaceMode}. + * + * @returns string The ANSI escape code for entering insert mode. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.insertMode + + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye " + + * Ansi.replaceMode, + * ); + * ``` + */ +export const insertMode = "\x1b[4h"; + +/** + * Causes existing characters to be overwritten at the cursor position by new + * characters. See also {@linkcode Ansi.insertMode}. + * + * @returns string The ANSI escape code for entering replace mode. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log("Hello World!"); + * await delay(1000); + * console.log( + * Ansi.insertMode + + * Ansi.moveCursorUp() + + * Ansi.setCursorColumn(7) + + * "and Goodbye " + + * Ansi.replaceMode, + * ); + * ``` + */ +export const replaceMode = "\x1b[4l"; + +/** + * Causes top and bottom margins to shrink to scrollable region (See + * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving + * to the lines outside it. + * + * @returns string The ANSI escape code for enabling origin mode. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setCursorPosition() + + * "Hello World" + + * Ansi.setScrollableRegion(2) + + * Ansi.enableOriginMode, + * ); + * await delay(1000); + * console.log(Ansi.setCursorPosition() + "Bye World!"); + * ``` + */ +export const enableOriginMode = "\x1b[?6h"; + +/** + * Causes the top and bottom margins to enlarge to the user's display. See + * {@linkcode Ansi.enableOriginMode}. + * + * @returns string The ANSI escape code for disabling origin mode. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setCursorPosition() + + * "Hello World" + + * Ansi.setScrollableRegion(2) + + * Ansi.enableOriginMode, + * ); + * await delay(1000); + * console.log(Ansi.setCursorPosition() + "Bye World!"); + * await delay(1000); + * console.log( + * Ansi.disableOriginMode + + * Ansi.setCursorPosition() + + * Ansi.eraseLine + + * "Hi World!", + * ); + * ``` + */ +export const disableOriginMode = "\x1b[?6l"; + +/** + * Causes cursor to automatically move to the next line when it hits the + * end of the current line to continue writing. See also + * {@linkcode Ansi.disableAutoWrap}. + * + * @returns string The ANSI escape code to enable auto-wrap. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.enableAutoWrap + "A" + "h".repeat(500)); + * ``` + */ +export const enableAutoWrap = "\x1b[?7h"; + +/** + * Causes cursor to remain on the same line when it hits the end of the + * current line. See also {@linkcode Ansi.enableAutoWrap}. + * + * @returns string The ANSI escape code to disable auto-wrap. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.disableAutoWrap + "A" + "h".repeat(500)); + * ``` + */ +export const disableAutoWrap = "\x1b[?7l"; + +/** + * Sets the cursor animation style. + * + * @param x The cursor style to set. + * @returns string The ANSI escape code to set the cursor style. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.setCursorStyle(Ansi.CursorStyle.BlinkingUnderline)); + * ``` + */ +export function setCursorStyle(x: CursorStyle): string { + return `\x1b[${x} q`; +} + +/** + * Causes cursor position to be visible to the user. See also + * {@linkcode Ansi.hideCursor}. + * + * @returns string The ANSI escape code to show the cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.showCursor); + * ``` + */ +export const showCursor = "\x1b[?25h"; + +/** + * Causes cursor position to be hidden from the user. See also + * {@linkcode Ansi.showCursor}. + * + * @returns string The ANSI escape code to hide the cursor. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log(Ansi.hideCursor); + * await delay(5000); + * console.log(Ansi.showCursor); + * ``` + */ +export const hideCursor = "\x1b[?25l"; + +/** + * Sets the scrollable region of the display. Allowing either or both the top + * and bottom lines to not have their content moved when the scrolling region + * is updated. `x` is the top line of the scrollable region. `y` is the + * bottom line of the scrollable region. + * + * @param x The top line of the scrollable region. + * @param y The bottom line of the scrollable region. + * @returns string The ANSI escape code to set the scrollable region. + * + * @example Usage + * ```ts ignore + * import * as Ansi from "@std/cli/unstable_ansi"; + * + * console.log( + * Ansi.eraseDisplay + + * Ansi.setScrollableRegion(3, 10), + * ); + * setInterval(() => console.log(Math.random()), 1000); + * ``` */ -export class Ansi { - /** - * Causes content on the current line to enlarge, showing only the top half - * of characters with each character taking up two columns. Can be used in - * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to - * make text appear twice as big. - * - * @returns string The ANSI escape code for double-height top. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); - * ``` - */ - static get doubleHeightTop(): string { - return "\x1b#3"; - } - - /** - * Causes content on the current line to enlarge, showing only the bottom - * half of the characters with each character taking up two columns. Can be - * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous - * line to make text appear twice as big. - * - * @returns string The ANSI escape code for double-height bottom. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); - * ``` - */ - static get doubleHeightBottom(): string { - return "\x1b#4"; - } - - /** - * Causes content on the current line to shrink down to a single column, - * essentially reverting the effects of {@linkcode Ansi.doubleHeightTop}, - * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. - * - * @returns string The ANSI escape code for single-width. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUpStart(2) + - * Ansi.deleteLines(1) + - * Ansi.singleWidth, - * ); - * ``` - */ - static get singleWidth(): string { - return "\x1b#5"; - } - - /** - * Causes content on the current line to stretch out, with each character - * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth}. - * - * @returns string The ANSI escape code for double-width. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.doubleWidth + "Hello World!"); - * ``` - */ - static get doubleWidth(): string { - return "\x1b#6"; - } - - /** - * Saves current cursor position that can later be restored with - * {@linkcode Ansi.restoreCursorPosition}. - * - * @returns string The ANSI escape code for saving cursor position. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.saveCursorPosition + - * Ansi.setCursorPosition(Deno.consoleSize().rows, 1) + - * Ansi.eraseLine + - * "Hello World!" + - * Ansi.restoreCursorPosition, - * ); - * ``` - */ - static get saveCursorPosition(): string { - return "\x1b7"; - } - - /** - * Restores cursor position that was earlier saved with - * {@linkcode Ansi.saveCursorPosition}. - * - * @returns string The ANSI escape code for restoring cursor position. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.saveCursorPosition + - * Ansi.setCursorPosition(Deno.consoleSize().rows) + - * Ansi.eraseLine + - * "Hello World!" + - * Ansi.restoreCursorPosition, - * ); - * ``` - */ - static get restoreCursorPosition(): string { - return "\x1b8"; - } - - /** - * This is a full reset of the terminal, reverting it back to its original - * default settings, clearing the screen, resetting modes, colors, character - * sets and more. Essentially making the terminal behave as if it were just - * started by the user. This command is very disruptive to the user. Also see - * {@linkcode Ansi.softReset}. - * - * @returns string The ANSI escape code for hard resetting the terminal. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.hideCursor); - * await delay(5000); - * console.log(Ansi.hardReset); - * ``` - */ - static get hardReset(): string { - return "\x1bc"; - } - - /** - * This command resets many settings to their initial state without fully - * reinitializing the terminal like {@linkcode Ansi.hardReset}. It preserves - * things like cursor position and display content, but clears modes, - * character sets, etc. Should probably be called when exiting the program. - * - * @returns string The ANSI escape code for soft resetting the terminal. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.hideCursor); - * await delay(5000); - * console.log(Ansi.softReset); - * ``` - */ - static get softReset(): string { - return "\x1b[!p"; - } - - /** - * Inserts `x` spaces at the cursor position. Shifting existing line content - * to the right. Cursor position does not change. Characters that exit the - * display are discarded. - * - * @param x The number of spaces to insert. - * @returns string The ANSI escape code for inserting spaces. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(6) + - * Ansi.insertSpace(10), - * ); - * ``` - */ - static insertSpace(x = 1): string { - return `\x1b[${x}@`; - } - - /** - * Deletes `x` characters at cursor position and to the right. Shifting line - * content left. - * - * @param x The number of characters to delete. - * @returns string The ANSI escape code for deleting characters. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUpStart() + - * Ansi.deleteCharacters(5) + - * "Bye", - * ); - * ``` - */ - static deleteCharacters(x = 1): string { - return `\x1b[${x}P`; - } - - /** - * Erases `x` characters at cursor position and to the right. - * - * @param x The number of characters to erase. - * @returns string The ANSI escape code for erasing characters. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * Ansi.eraseCharacters(6) + - * "Bob!", - * ); - * ``` - */ - static eraseCharacters(x = 1): string { - return `\x1b[${x}X`; - } - - /** - * Inserts `x` lines at cursor position. Shifting current line and below - * down. Cursor position does not change. Characters that exit the display - * are discarded. - * - * @param x The number of lines to insert. - * @returns string The ANSI escape code for inserting lines. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUpStart() + - * Ansi.insertLines() + - * "and Goodbye", - * ); - * ``` - */ - static insertLines(x = 1): string { - return `\x1b[${x}L`; - } - - /** - * Deletes `x` lines at cursor position. Shifting below lines up. - * - * @param x The number of lines to delete. - * @returns string The ANSI escape code for deleting lines. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log(Ansi.moveCursorUpStart() + Ansi.deleteLines()); - * await delay(1000); - * console.log("and Goodbye!"); - * ``` - */ - static deleteLines(x = 1): string { - return `\x1b[${x}M`; - } - - /** - * Moves cursor position up `x` lines or up to the top margin. - * - * @param x The number of lines to move up. - * @returns string The ANSI escape code for moving the cursor up. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log(Ansi.moveCursorUp(2) + "Goodbye"); - * ``` - */ - static moveCursorUp(x = 1): string { - return `\x1b[${x}A`; - } - - /** - * Moves cursor position `x` lines up or up to the top of the margin, and to - * the beginning of that line. - * - * @param x The number of lines to move up. - * @returns string The ANSI escape code for moving the cursor up and to the - * beginning of the line. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log(Ansi.moveCursorUpStart(2) + "Goodbye"); - * ``` - */ - static moveCursorUpStart(x = 1): string { - return `\x1b[${x}F`; - } - - /** - * Moves cursor position down `x` lines or up to the bottom margin. - * - * @param x The number of lines to move down. - * @returns string The ANSI escape code for moving the cursor down. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUpStart(2) + - * "Goodbye" + - * Ansi.moveCursorDown() + - * Ansi.setCursorColumn() + - * Ansi.eraseLine + - * "Bob!", - * ); - * ``` - */ - static moveCursorDown(x = 1): string { - return `\x1b[${x}B`; - } - - /** - * Moves cursor position `x` lines down or up to the bottom margin, and to - * the beginning of that line. - * - * @param x The number of lines to move down. - * @returns string The ANSI escape code for moving the cursor down and to the - * beginning of the line. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello\nWorld!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUpStart(2) + - * "Goodbye" + - * Ansi.moveCursorDownStart() + - * Ansi.eraseLine + - * "Bob!", - * ); - * ``` - */ - static moveCursorDownStart(x = 1): string { - return `\x1b[${x}E`; - } - - /** - * Moves cursor position `x` columns right or up to the right margin. - * - * @param x The number of columns to move right. - * @returns string The ANSI escape code for moving the cursor right. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.moveCursorRight(2) + "Hello World!"); - * ``` - */ - static moveCursorRight(x = 1): string { - return `\x1b[${x}C`; - } - - /** - * Moves cursor position `x` tab stops right or up to the right margin. - * - * @param x The number of tab stops to move right. - * @returns string The ANSI escape code for moving the cursor right every tab - * stop. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.moveCursorRightTab() + "Hello World!"); - * ``` - */ - static moveCursorRightTab(x = 1): string { - return `\x1b[${x}I`; - } - - /** - * Moves cursor position `x` columns left or up to the left margin. - * - * @param x The number of columns to move left. - * @returns string The ANSI escape code for moving the cursor left. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.moveCursorRight(4) + - * Ansi.moveCursorLeft(2) + - * "Hello World!", - * ); - * ``` - */ - static moveCursorLeft(x = 1): string { - return `\x1b[${x}D`; - } - - /** - * Moves cursor position `x` tab stops left or up to the left margin. - * - * @param x The number of tab stops to move left. - * @returns string The ANSI escape code for moving the cursor left every tab - * stop. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.moveCursorRightTab(2) + - * Ansi.moveCursorLeftTab() + - * "Hello World!", - * ); - * ``` - */ - static moveCursorLeftTab(x = 1): string { - return `\x1b[${x}Z`; - } - - /** - * Sets cursor position to column `x` or up to the sides of the margins. - * Columns begin at `1` not `0`. - * - * @param x The column to move to. - * @returns string The ANSI escape code for setting the cursor column. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * "and Goodbye!", - * ); - * ``` - */ - static setCursorColumn(x = 1): string { - return `\x1b[${x}G`; - } - - /** - * Sets cursor position to line `x` or down to the bottom of the margin. - * Lines begin at `1` not `0`. - * - * @param x The line to move to. - * @returns string The ANSI escape code for setting the cursor line. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.setCursorLine() + Ansi.eraseLine + "Hello World!"); - * ``` - */ - static setCursorLine(x = 1): string { - return `\x1b[${x}d`; - } - - /** - * Sets cursor position to `x` line and `y` column or up to the margin. Lines - * and columns begin at `1` not `0`. - * - * @param x The line to move to. - * @param y The column to move to. - * @returns string The ANSI escape code for setting the cursor position. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.setCursorPosition(5, 2) + - * Ansi.eraseLine + - * "Hello World!", - * ); - * ``` - */ - static setCursorPosition(x = 1, y = 1): string { - return `\x1b[${x};${y}H`; - } - - /** - * Erases line content to the right of cursor position. - * - * @returns string The ANSI escape code for erasing the line content to the - * right of the cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * Ansi.eraseLineAfterCursor, - * ); - * ``` - */ - static get eraseLineAfterCursor(): string { - return "\x1b[0K"; - } - - /** - * Erases line content to the left of cursor position. - * - * @returns string The ANSI escape code for erasing the line content to the - * left of the cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * Ansi.eraseLineBeforeCursor, - * ); - * ``` - */ - static get eraseLineBeforeCursor(): string { - return "\x1b[1K"; - } - - /** - * Erases entire line content. - * - * @returns string The ANSI escape code for erasing the entire line content. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log(Ansi.moveCursorUp() + Ansi.eraseLine); - * ``` - */ - static get eraseLine(): string { - return "\x1b[2K"; - } - - /** - * Erases content of lines below cursor position and content to the right on - * the same line as cursor. - * - * @returns string The ANSI escape code for erasing the content after the - * cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * Ansi.eraseDisplayAfterCursor, - * ); - * ``` - */ - static get eraseDisplayAfterCursor(): string { - return "\x1b[0J"; - } - - /** - * Erases content of lines above cursor position and content to the left on - * the same line as cursor. - * - * @returns string The ANSI escape code for erasing the content before the - * cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * Ansi.eraseDisplayBeforeCursor, - * ); - * ``` - */ - static get eraseDisplayBeforeCursor(): string { - return "\x1b[1J"; - } - - /** - * Erases all content. - * - * @returns string The ANSI escape code for erasing the entire display. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log(Ansi.eraseDisplay); - * ``` - */ - static get eraseDisplay(): string { - return "\x1b[2J"; - } - - /** - * Shifts content within the scrollable region up `x` lines, inserting blank - * lines at the bottom of the scrollable region. - * - * @param x The number of lines content should be shifted up. - * @returns string The ANSI escape code for shifting content up. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.shiftUpAndInsert()); - * ``` - */ - static shiftUpAndInsert(x = 1): string { - return `\x1b[${x}S`; - } - - /** - * Shifts content within the scrollable region down `x` lines, inserting - * blank lines at the top of the scrollable region. - * - * @param x The number of lines content should be shifted down. - * @returns string The ANSI escape code for shifting content down. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.shiftDownAndInsert(3)); - * ``` - */ - static shiftDownAndInsert(x = 1): string { - return `\x1b[${x}T`; - } - - /** - * Repeats last graphic character printed `x` times at cursor position. - * - * @param x The number of times the last character printed should be repeated. - * @returns string The ANSI escape code for repeating the last printed - * character. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!" + Ansi.repeatLastCharacter(4)); - * ``` - */ - static repeatLastCharacter(x = 1): string { - return `\x1b[${x}b`; - } - - /** - * Causes existing characters to the right of the cursor position to shift - * right as new characters are written. Opposite of - * {@linkcode Ansi.replaceMode}. - * - * @returns string The ANSI escape code for entering insert mode. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.insertMode + - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * "and Goodbye " + - * Ansi.replaceMode, - * ); - * ``` - */ - static get insertMode(): string { - return "\x1b[4h"; - } - - /** - * Causes existing characters to be overwritten at the cursor position by new - * characters. See also {@linkcode Ansi.insertMode}. - * - * @returns string The ANSI escape code for entering replace mode. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log("Hello World!"); - * await delay(1000); - * console.log( - * Ansi.insertMode + - * Ansi.moveCursorUp() + - * Ansi.setCursorColumn(7) + - * "and Goodbye " + - * Ansi.replaceMode, - * ); - * ``` - */ - static get replaceMode(): string { - return "\x1b[4l"; - } - - /** - * Causes top and bottom margins to shrink to scrollable region (See - * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving - * to the lines outside it. - * - * @returns string The ANSI escape code for enabling origin mode. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.eraseDisplay + - * Ansi.setCursorPosition() + - * "Hello World" + - * Ansi.setScrollableRegion(2) + - * Ansi.enableOriginMode, - * ); - * await delay(1000); - * console.log(Ansi.setCursorPosition() + "Bye World!"); - * ``` - */ - static get enableOriginMode(): string { - return "\x1b[?6h"; - } - - /** - * Causes the top and bottom margins to enlarge to the user's display. See - * {@linkcode Ansi.enableOriginMode}. - * - * @returns string The ANSI escape code for disabling origin mode. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.eraseDisplay + - * Ansi.setCursorPosition() + - * "Hello World" + - * Ansi.setScrollableRegion(2) + - * Ansi.enableOriginMode, - * ); - * await delay(1000); - * console.log(Ansi.setCursorPosition() + "Bye World!"); - * await delay(1000); - * console.log( - * Ansi.disableOriginMode + - * Ansi.setCursorPosition() + - * Ansi.eraseLine + - * "Hi World!", - * ); - * ``` - */ - static get disableOriginMode(): string { - return "\x1b[?6l"; - } - - /** - * Causes cursor to automatically move to the next line when it hits the - * end of the current line to continue writing. See also - * {@linkcode Ansi.disableAutoWrap}. - * - * @returns string The ANSI escape code to enable auto-wrap. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.enableAutoWrap + "A" + "h".repeat(500)); - * ``` - */ - static get enableAutoWrap(): string { - return "\x1b[?7h"; - } - - /** - * Causes cursor to remain on the same line when it hits the end of the - * current line. See also {@linkcode Ansi.enableAutoWrap}. - * - * @returns string The ANSI escape code to disable auto-wrap. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.disableAutoWrap + "A" + "h".repeat(500)); - * ``` - */ - static get disableAutoWrap(): string { - return "\x1b[?7l"; - } - - /** - * Sets the cursor animation style. - * - * @param x The cursor style to set. - * @returns string The ANSI escape code to set the cursor style. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.setCursorStyle(CursorStyle.BlinkingUnderline)); - * ``` - */ - static setCursorStyle(x: CursorStyle): string { - return `\x1b[${x} q`; - } - - /** - * Causes cursor position to be visible to the user. See also - * {@linkcode Ansi.hideCursor}. - * - * @returns string The ANSI escape code to show the cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.hideCursor); - * await delay(5000); - * console.log(Ansi.showCursor); - * ``` - */ - static get showCursor(): string { - return "\x1b[?25h"; - } - - /** - * Causes cursor position to be hidden from the user. See also - * {@linkcode Ansi.showCursor}. - * - * @returns string The ANSI escape code to hide the cursor. - * - * @example Usage - * ```ts ignore - * import { delay } from "@std/async/delay"; - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log(Ansi.hideCursor); - * await delay(5000); - * console.log(Ansi.showCursor); - * ``` - */ - static get hideCursor(): string { - return "\x1b[?25l"; - } - - /** - * Sets the scrollable region of the display. Allowing either or both the top - * and bottom lines to not have their content moved when the scrolling region - * is updated. `x` is the top line of the scrollable region. `y` is the - * bottom line of the scrollable region. - * - * @param x The top line of the scrollable region. - * @param y The bottom line of the scrollable region. - * @returns string The ANSI escape code to set the scrollable region. - * - * @example Usage - * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; - * - * console.log( - * Ansi.eraseDisplay + - * Ansi.setScrollableRegion(3, 10), - * ); - * setInterval(() => console.log(Math.random()), 1000); - * ``` - */ - static setScrollableRegion(x = 1, y?: number): string { - return `\x1b[${x}${y == undefined ? "" : `;${y}`}r`; - } +export function setScrollableRegion(x = 1, y?: number): string { + return `\x1b[${x}${y == undefined ? "" : `;${y}`}r`; } /** - * CursorStyle is a const enum used to set the value in + * CursorStyle is a export const enum used to set the value in * {@linkcode Ansi.setCursorStyle}. * * @example Usage * ```ts ignore - * import { Ansi } from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable_ansi"; * - * console.log(Ansi.setCursorStyle(CursorStyle.BlinkingUnderline)); + * console.log(Ansi.setCursorStyle(Ansi.CursorStyle.BlinkingUnderline)); * ``` */ export const enum CursorStyle { From df3c7c79e57a5a35a2c24759b59dbcb6fa1aa1f9 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:02:26 +1000 Subject: [PATCH 12/25] update(cli): import statement to reflect ansi branch --- cli/unstable_static_line.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 31f6becf144c..6bb34b6dd4da 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -1,6 +1,6 @@ // Copyright 2018-2025 the Deno authors. MIT license. -import { Ansi } from "./unstable_ansi.ts"; +import * as Ansi from "./unstable_ansi.ts"; let nextID = 0; const linesAtTop: number[] = []; From 1eb5ab51f3bb94eddd73c12e007ced760dc5abca Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:12:41 +1000 Subject: [PATCH 13/25] fix(cli): Missing Deno keyword --- cli/unstable_static_line.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 6bb34b6dd4da..26c7168a895f 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -14,8 +14,9 @@ const getRows = "Deno" in globalThis const write = "Deno" in globalThis ? (() => { const encoder = new TextEncoder(); - // deno-lint-ignore no-explicit-any - return (x: string) => (globalThis as any).stderr.write(encoder.encode(x)); + return (x: string) => + // deno-lint-ignore no-explicit-any + (globalThis as any).Deno.stderr.write(encoder.encode(x)); })() // deno-lint-ignore no-explicit-any : (x: string) => (globalThis as any).process.stderr.write(x); From 4146773d8bb4403a2c458fd15a6a8b5113e0743e Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Wed, 16 Jul 2025 20:13:16 +1000 Subject: [PATCH 14/25] switch(cli): Ansi codes due to slightly different functionality --- cli/unstable_ansi.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index af8399c15df2..5ee50775dabd 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -118,7 +118,7 @@ export const doubleWidth = "\x1b#6"; * ); * ``` */ -export const saveCursorPosition = "\x1b7"; +export const saveCursorPosition = "\x1b[s"; /** * Restores cursor position that was earlier saved with @@ -139,7 +139,7 @@ export const saveCursorPosition = "\x1b7"; * ); * ``` */ -export const restoreCursorPosition = "\x1b8"; +export const restoreCursorPosition = "\x1b[u"; /** * This is a full reset of the terminal, reverting it back to its original From bf4a93bdf51748d86ea82136657389f99dd2f009 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Wed, 9 Jul 2025 19:49:48 +1000 Subject: [PATCH 15/25] feat(cli): StaticLine --- cli/deno.json | 1 + cli/unstable_static_line.ts | 155 ++++++++++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 cli/unstable_static_line.ts diff --git a/cli/deno.json b/cli/deno.json index bd336083b2d5..a1b600fc0a13 100644 --- a/cli/deno.json +++ b/cli/deno.json @@ -11,6 +11,7 @@ "./unstable-prompt-select": "./unstable_prompt_select.ts", "./unstable-prompt-multiple-select": "./unstable_prompt_multiple_select.ts", "./unstable-spinner": "./unstable_spinner.ts", + "./unstable-static-line": "./unstable_static_line.ts", "./unicode-width": "./unicode_width.ts" } } diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts new file mode 100644 index 000000000000..31f6becf144c --- /dev/null +++ b/cli/unstable_static_line.ts @@ -0,0 +1,155 @@ +// Copyright 2018-2025 the Deno authors. MIT license. + +import { Ansi } from "./unstable_ansi.ts"; + +let nextID = 0; +const linesAtTop: number[] = []; +const linesAtBottom: number[] = []; + +const getRows = "Deno" in globalThis + // deno-lint-ignore no-explicit-any + ? (): number => (globalThis as any).Deno.consoleSize().rows + // deno-lint-ignore no-explicit-any + : (): number => (globalThis as any).process.stderr.rows; +const write = "Deno" in globalThis + ? (() => { + const encoder = new TextEncoder(); + // deno-lint-ignore no-explicit-any + return (x: string) => (globalThis as any).stderr.write(encoder.encode(x)); + })() + // deno-lint-ignore no-explicit-any + : (x: string) => (globalThis as any).process.stderr.write(x); + +/** + * StaticLine is a class that assigns a line in the terminal for you to write + * to and that won't be overwritten by `console.log`. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ +export class StaticLine { + #id = ++nextID; + #atTop: boolean; + #lines: number[]; + #released = false; + /** + * Constructs a new instance. + * + * @param atTop Whether the line should be at the top or bottom of the + * terminal. + */ + constructor(atTop = false) { + this.#atTop = atTop; + this.#lines = atTop ? linesAtTop : linesAtBottom; + this.#lines.push(this.#id); + const top = linesAtTop.length + 1; + const bottom = getRows() - linesAtBottom.length; + write( + (atTop ? "" : Ansi.shiftUpAndInsert()) + + Ansi.setScrollableRegion(top, bottom) + + Ansi.setCursorPosition(bottom), + ); + } + + /** + * Overwrites the contents of the line. + * + * @param line The new content to write. + * @returns A promise that resolves when the line is written. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ + async write(line: string): Promise { + if (this.#released) throw new ReferenceError("Line has been released"); + await write( + Ansi.saveCursorPosition + + Ansi.disableAutoWrap + + Ansi.setCursorPosition( + this.#atTop + ? linesAtTop.indexOf(this.#id) + 1 + : getRows() - linesAtBottom.indexOf(this.#id), + ) + + Ansi.eraseLine + + line + + Ansi.enableAutoWrap + + Ansi.restoreCursorPosition, + ); + } + + /** + * Releases the line so other content can use it. + * + * @returns A promise that resolves when the line is released. + * + * @example Usage + * ```ts ignore + * import { delay } from "@std/async/delay"; + * import { StaticLine } from "@std/cli/unstable-static-line"; + * + * const id = setInterval(() => console.log(Math.random()), 1000); + * + * const line = new StaticLine(); + * await line.write("Hello World!"); + * await delay(1500); + * await line.write("How are you?"); + * await delay(1500); + * await line.write("Doing good?"); + * await delay(1500); + * await line.releaseLine(); + * ``` + */ + async releaseLine(): Promise { + if (this.#released) return; + this.#released = true; + const index = this.#lines.indexOf(this.#id); + this.#lines.splice(index, 1); + const rows = getRows(); + const top = linesAtTop.length + 1; + const bottom = rows - linesAtBottom.length; + await write( + Ansi.saveCursorPosition + + (this.#atTop + ? Ansi.setScrollableRegion(index + 1, top + 1) + + Ansi.shiftUpAndInsert() + : (linesAtBottom.length + ? Ansi.setScrollableRegion( + bottom, + rows - index, + ) + + Ansi.shiftDownAndInsert() + : Ansi.setCursorPosition(rows) + + Ansi.eraseLine)) + + Ansi.setScrollableRegion(top, bottom) + + Ansi.restoreCursorPosition, + ); + } +} From 60c9da18a483b4616ddf54e05fc62dcf73973451 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:02:26 +1000 Subject: [PATCH 16/25] update(cli): import statement to reflect ansi branch --- cli/unstable_static_line.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 31f6becf144c..6bb34b6dd4da 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -1,6 +1,6 @@ // Copyright 2018-2025 the Deno authors. MIT license. -import { Ansi } from "./unstable_ansi.ts"; +import * as Ansi from "./unstable_ansi.ts"; let nextID = 0; const linesAtTop: number[] = []; From e507dce32df717fb29cc17635f3a7370c79de881 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Fri, 11 Jul 2025 21:12:41 +1000 Subject: [PATCH 17/25] fix(cli): Missing Deno keyword --- cli/unstable_static_line.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 6bb34b6dd4da..26c7168a895f 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -14,8 +14,9 @@ const getRows = "Deno" in globalThis const write = "Deno" in globalThis ? (() => { const encoder = new TextEncoder(); - // deno-lint-ignore no-explicit-any - return (x: string) => (globalThis as any).stderr.write(encoder.encode(x)); + return (x: string) => + // deno-lint-ignore no-explicit-any + (globalThis as any).Deno.stderr.write(encoder.encode(x)); })() // deno-lint-ignore no-explicit-any : (x: string) => (globalThis as any).process.stderr.write(x); From da702c93f8750b9db0514361b4947ef0e4c454c2 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Wed, 16 Jul 2025 20:56:32 +1000 Subject: [PATCH 18/25] revert(cli): last changes to Ansi codes --- cli/unstable_ansi.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index 5ee50775dabd..af8399c15df2 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -118,7 +118,7 @@ export const doubleWidth = "\x1b#6"; * ); * ``` */ -export const saveCursorPosition = "\x1b[s"; +export const saveCursorPosition = "\x1b7"; /** * Restores cursor position that was earlier saved with @@ -139,7 +139,7 @@ export const saveCursorPosition = "\x1b[s"; * ); * ``` */ -export const restoreCursorPosition = "\x1b[u"; +export const restoreCursorPosition = "\x1b8"; /** * This is a full reset of the terminal, reverting it back to its original From 552303936a73938ce98a5e22c697598209ff96e9 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Thu, 17 Jul 2025 12:07:43 +1000 Subject: [PATCH 19/25] docs(cli): fixed for Ansi module --- cli/unstable_ansi.ts | 212 +++++++++++++++++++++---------------------- 1 file changed, 106 insertions(+), 106 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index af8399c15df2..f5f0ef5ed74f 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -15,7 +15,7 @@ * * @example Basic Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.doubleHeightTop + "Hello World!"); * console.log(Ansi.doubleHeightBottom + "Hello World!"); @@ -27,14 +27,14 @@ /** * Causes content on the current line to enlarge, showing only the top half * of characters with each character taking up two columns. Can be used in - * combination with {@linkcode Ansi.doubleHeightBottom} on the next line to + * combination with {@linkcode doubleHeightBottom} on the next line to * make text appear twice as big. * - * @returns string The ANSI escape code for double-height top. + * @returns The ANSI escape code for double-height top. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.doubleHeightTop + "Hello World!"); * console.log(Ansi.doubleHeightBottom + "Hello World!"); @@ -45,14 +45,14 @@ export const doubleHeightTop = "\x1b#3"; /** * Causes content on the current line to enlarge, showing only the bottom * half of the characters with each character taking up two columns. Can be - * used in combination with {@linkcode Ansi.doubleHeightTop} on the previous + * used in combination with {@linkcode doubleHeightTop} on the previous * line to make text appear twice as big. * - * @returns string The ANSI escape code for double-height bottom. + * @returns The ANSI escape code for double-height bottom. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.doubleHeightTop + "Hello World!"); * console.log(Ansi.doubleHeightBottom + "Hello World!"); @@ -62,15 +62,15 @@ export const doubleHeightBottom = "\x1b#4"; /** * Causes content on the current line to shrink down to a single column, - * essentially reverting the effects of {@linkcode Ansi.doubleHeightTop}, - * {@linkcode Ansi.doubleHeightBottom}, or {@linkcode Ansi.doubleWidth}. + * essentially reverting the effects of {@linkcode doubleHeightTop}, + * {@linkcode doubleHeightBottom}, or {@linkcode doubleWidth}. * - * @returns string The ANSI escape code for single-width. + * @returns The ANSI escape code for single-width. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.doubleHeightTop + "Hello World!"); * console.log(Ansi.doubleHeightBottom + "Hello World!"); @@ -86,13 +86,13 @@ export const singleWidth = "\x1b#5"; /** * Causes content on the current line to stretch out, with each character - * taking up two columns. Can be reverted with {@linkcode Ansi.singleWidth}. + * taking up two columns. Can be reverted with {@linkcode singleWidth}. * - * @returns string The ANSI escape code for double-width. + * @returns The ANSI escape code for double-width. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.doubleWidth + "Hello World!"); * ``` @@ -101,13 +101,13 @@ export const doubleWidth = "\x1b#6"; /** * Saves current cursor position that can later be restored with - * {@linkcode Ansi.restoreCursorPosition}. + * {@linkcode restoreCursorPosition}. * - * @returns string The ANSI escape code for saving cursor position. + * @returns The ANSI escape code for saving cursor position. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.saveCursorPosition + @@ -122,13 +122,13 @@ export const saveCursorPosition = "\x1b7"; /** * Restores cursor position that was earlier saved with - * {@linkcode Ansi.saveCursorPosition}. + * {@linkcode saveCursorPosition}. * - * @returns string The ANSI escape code for restoring cursor position. + * @returns The ANSI escape code for restoring cursor position. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.saveCursorPosition + @@ -146,14 +146,14 @@ export const restoreCursorPosition = "\x1b8"; * default settings, clearing the screen, resetting modes, colors, character * sets and more. Essentially making the terminal behave as if it were just * started by the user. This command is very disruptive to the user. Also see - * {@linkcode Ansi.softReset}. + * {@linkcode softReset}. * - * @returns string The ANSI escape code for hard resetting the terminal. + * @returns The ANSI escape code for hard resetting the terminal. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.hideCursor); * await delay(5000); @@ -164,16 +164,16 @@ export const hardReset = "\x1bc"; /** * This command resets many settings to their initial state without fully - * reinitializing the terminal like {@linkcode Ansi.hardReset}. It preserves + * reinitializing the terminal like {@linkcode hardReset}. It preserves * things like cursor position and display content, but clears modes, * character sets, etc. Should probably be called when exiting the program. * - * @returns string The ANSI escape code for soft resetting the terminal. + * @returns The ANSI escape code for soft resetting the terminal. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.hideCursor); * await delay(5000); @@ -188,12 +188,12 @@ export const softReset = "\x1b[!p"; * display are discarded. * * @param x The number of spaces to insert. - * @returns string The ANSI escape code for inserting spaces. + * @returns The ANSI escape code for inserting spaces. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -213,12 +213,12 @@ export function insertSpace(x = 1): string { * content left. * * @param x The number of characters to delete. - * @returns string The ANSI escape code for deleting characters. + * @returns The ANSI escape code for deleting characters. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -237,12 +237,12 @@ export function deleteCharacters(x = 1): string { * Erases `x` characters at cursor position and to the right. * * @param x The number of characters to erase. - * @returns string The ANSI escape code for erasing characters. + * @returns The ANSI escape code for erasing characters. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -264,12 +264,12 @@ export function eraseCharacters(x = 1): string { * are discarded. * * @param x The number of lines to insert. - * @returns string The ANSI escape code for inserting lines. + * @returns The ANSI escape code for inserting lines. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -288,12 +288,12 @@ export function insertLines(x = 1): string { * Deletes `x` lines at cursor position. Shifting below lines up. * * @param x The number of lines to delete. - * @returns string The ANSI escape code for deleting lines. + * @returns The ANSI escape code for deleting lines. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -310,12 +310,12 @@ export function deleteLines(x = 1): string { * Moves cursor position up `x` lines or up to the top margin. * * @param x The number of lines to move up. - * @returns string The ANSI escape code for moving the cursor up. + * @returns The ANSI escape code for moving the cursor up. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -331,13 +331,13 @@ export function moveCursorUp(x = 1): string { * the beginning of that line. * * @param x The number of lines to move up. - * @returns string The ANSI escape code for moving the cursor up and to the + * @returns The ANSI escape code for moving the cursor up and to the * beginning of the line. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -352,12 +352,12 @@ export function moveCursorUpStart(x = 1): string { * Moves cursor position down `x` lines or up to the bottom margin. * * @param x The number of lines to move down. - * @returns string The ANSI escape code for moving the cursor down. + * @returns The ANSI escape code for moving the cursor down. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -380,13 +380,13 @@ export function moveCursorDown(x = 1): string { * the beginning of that line. * * @param x The number of lines to move down. - * @returns string The ANSI escape code for moving the cursor down and to the + * @returns The ANSI escape code for moving the cursor down and to the * beginning of the line. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello\nWorld!"); * await delay(1000); @@ -407,11 +407,11 @@ export function moveCursorDownStart(x = 1): string { * Moves cursor position `x` columns right or up to the right margin. * * @param x The number of columns to move right. - * @returns string The ANSI escape code for moving the cursor right. + * @returns The ANSI escape code for moving the cursor right. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.moveCursorRight(2) + "Hello World!"); * ``` @@ -424,12 +424,12 @@ export function moveCursorRight(x = 1): string { * Moves cursor position `x` tab stops right or up to the right margin. * * @param x The number of tab stops to move right. - * @returns string The ANSI escape code for moving the cursor right every tab + * @returns The ANSI escape code for moving the cursor right every tab * stop. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.moveCursorRightTab() + "Hello World!"); * ``` @@ -442,11 +442,11 @@ export function moveCursorRightTab(x = 1): string { * Moves cursor position `x` columns left or up to the left margin. * * @param x The number of columns to move left. - * @returns string The ANSI escape code for moving the cursor left. + * @returns The ANSI escape code for moving the cursor left. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.moveCursorRight(4) + @@ -463,12 +463,12 @@ export function moveCursorLeft(x = 1): string { * Moves cursor position `x` tab stops left or up to the left margin. * * @param x The number of tab stops to move left. - * @returns string The ANSI escape code for moving the cursor left every tab + * @returns The ANSI escape code for moving the cursor left every tab * stop. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.moveCursorRightTab(2) + @@ -486,12 +486,12 @@ export function moveCursorLeftTab(x = 1): string { * Columns begin at `1` not `0`. * * @param x The column to move to. - * @returns string The ANSI escape code for setting the cursor column. + * @returns The ANSI escape code for setting the cursor column. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -511,11 +511,11 @@ export function setCursorColumn(x = 1): string { * Lines begin at `1` not `0`. * * @param x The line to move to. - * @returns string The ANSI escape code for setting the cursor line. + * @returns The ANSI escape code for setting the cursor line. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.setCursorLine() + Ansi.eraseLine + "Hello World!"); * ``` @@ -530,11 +530,11 @@ export function setCursorLine(x = 1): string { * * @param x The line to move to. * @param y The column to move to. - * @returns string The ANSI escape code for setting the cursor position. + * @returns The ANSI escape code for setting the cursor position. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.setCursorPosition(5, 2) + @@ -550,13 +550,13 @@ export function setCursorPosition(x = 1, y = 1): string { /** * Erases line content to the right of cursor position. * - * @returns string The ANSI escape code for erasing the line content to the + * @returns The ANSI escape code for erasing the line content to the * right of the cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -572,13 +572,13 @@ export const eraseLineAfterCursor = "\x1b[0K"; /** * Erases line content to the left of cursor position. * - * @returns string The ANSI escape code for erasing the line content to the + * @returns The ANSI escape code for erasing the line content to the * left of the cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -594,12 +594,12 @@ export const eraseLineBeforeCursor = "\x1b[1K"; /** * Erases entire line content. * - * @returns string The ANSI escape code for erasing the entire line content. + * @returns The ANSI escape code for erasing the entire line content. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -612,13 +612,13 @@ export const eraseLine = "\x1b[2K"; * Erases content of lines below cursor position and content to the right on * the same line as cursor. * - * @returns string The ANSI escape code for erasing the content after the + * @returns The ANSI escape code for erasing the content after the * cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -635,13 +635,13 @@ export const eraseDisplayAfterCursor = "\x1b[0J"; * Erases content of lines above cursor position and content to the left on * the same line as cursor. * - * @returns string The ANSI escape code for erasing the content before the + * @returns The ANSI escape code for erasing the content before the * cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -657,12 +657,12 @@ export const eraseDisplayBeforeCursor = "\x1b[1J"; /** * Erases all content. * - * @returns string The ANSI escape code for erasing the entire display. + * @returns The ANSI escape code for erasing the entire display. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -676,11 +676,11 @@ export const eraseDisplay = "\x1b[2J"; * lines at the bottom of the scrollable region. * * @param x The number of lines content should be shifted up. - * @returns string The ANSI escape code for shifting content up. + * @returns The ANSI escape code for shifting content up. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.shiftUpAndInsert()); * ``` @@ -694,11 +694,11 @@ export function shiftUpAndInsert(x = 1): string { * blank lines at the top of the scrollable region. * * @param x The number of lines content should be shifted down. - * @returns string The ANSI escape code for shifting content down. + * @returns The ANSI escape code for shifting content down. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.shiftDownAndInsert(3)); * ``` @@ -711,12 +711,12 @@ export function shiftDownAndInsert(x = 1): string { * Repeats last graphic character printed `x` times at cursor position. * * @param x The number of times the last character printed should be repeated. - * @returns string The ANSI escape code for repeating the last printed + * @returns The ANSI escape code for repeating the last printed * character. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!" + Ansi.repeatLastCharacter(4)); * ``` @@ -728,14 +728,14 @@ export function repeatLastCharacter(x = 1): string { /** * Causes existing characters to the right of the cursor position to shift * right as new characters are written. Opposite of - * {@linkcode Ansi.replaceMode}. + * {@linkcode replaceMode}. * - * @returns string The ANSI escape code for entering insert mode. + * @returns The ANSI escape code for entering insert mode. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -752,14 +752,14 @@ export const insertMode = "\x1b[4h"; /** * Causes existing characters to be overwritten at the cursor position by new - * characters. See also {@linkcode Ansi.insertMode}. + * characters. See also {@linkcode insertMode}. * - * @returns string The ANSI escape code for entering replace mode. + * @returns The ANSI escape code for entering replace mode. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log("Hello World!"); * await delay(1000); @@ -776,15 +776,15 @@ export const replaceMode = "\x1b[4l"; /** * Causes top and bottom margins to shrink to scrollable region (See - * {@linkcode Ansi.setScrollableRegion}) preventing the cursor from moving + * {@linkcode setScrollableRegion}) preventing the cursor from moving * to the lines outside it. * - * @returns string The ANSI escape code for enabling origin mode. + * @returns The ANSI escape code for enabling origin mode. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.eraseDisplay + @@ -801,14 +801,14 @@ export const enableOriginMode = "\x1b[?6h"; /** * Causes the top and bottom margins to enlarge to the user's display. See - * {@linkcode Ansi.enableOriginMode}. + * {@linkcode enableOriginMode}. * - * @returns string The ANSI escape code for disabling origin mode. + * @returns The ANSI escape code for disabling origin mode. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.eraseDisplay + @@ -833,13 +833,13 @@ export const disableOriginMode = "\x1b[?6l"; /** * Causes cursor to automatically move to the next line when it hits the * end of the current line to continue writing. See also - * {@linkcode Ansi.disableAutoWrap}. + * {@linkcode disableAutoWrap}. * - * @returns string The ANSI escape code to enable auto-wrap. + * @returns The ANSI escape code to enable auto-wrap. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.enableAutoWrap + "A" + "h".repeat(500)); * ``` @@ -848,13 +848,13 @@ export const enableAutoWrap = "\x1b[?7h"; /** * Causes cursor to remain on the same line when it hits the end of the - * current line. See also {@linkcode Ansi.enableAutoWrap}. + * current line. See also {@linkcode enableAutoWrap}. * - * @returns string The ANSI escape code to disable auto-wrap. + * @returns The ANSI escape code to disable auto-wrap. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.disableAutoWrap + "A" + "h".repeat(500)); * ``` @@ -865,11 +865,11 @@ export const disableAutoWrap = "\x1b[?7l"; * Sets the cursor animation style. * * @param x The cursor style to set. - * @returns string The ANSI escape code to set the cursor style. + * @returns The ANSI escape code to set the cursor style. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.setCursorStyle(Ansi.CursorStyle.BlinkingUnderline)); * ``` @@ -880,14 +880,14 @@ export function setCursorStyle(x: CursorStyle): string { /** * Causes cursor position to be visible to the user. See also - * {@linkcode Ansi.hideCursor}. + * {@linkcode hideCursor}. * - * @returns string The ANSI escape code to show the cursor. + * @returns The ANSI escape code to show the cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.hideCursor); * await delay(5000); @@ -898,14 +898,14 @@ export const showCursor = "\x1b[?25h"; /** * Causes cursor position to be hidden from the user. See also - * {@linkcode Ansi.showCursor}. + * {@linkcode showCursor}. * - * @returns string The ANSI escape code to hide the cursor. + * @returns The ANSI escape code to hide the cursor. * * @example Usage * ```ts ignore * import { delay } from "@std/async/delay"; - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.hideCursor); * await delay(5000); @@ -922,11 +922,11 @@ export const hideCursor = "\x1b[?25l"; * * @param x The top line of the scrollable region. * @param y The bottom line of the scrollable region. - * @returns string The ANSI escape code to set the scrollable region. + * @returns The ANSI escape code to set the scrollable region. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( * Ansi.eraseDisplay + @@ -941,11 +941,11 @@ export function setScrollableRegion(x = 1, y?: number): string { /** * CursorStyle is a export const enum used to set the value in - * {@linkcode Ansi.setCursorStyle}. + * {@linkcode setCursorStyle}. * * @example Usage * ```ts ignore - * import * as Ansi from "@std/cli/unstable_ansi"; + * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log(Ansi.setCursorStyle(Ansi.CursorStyle.BlinkingUnderline)); * ``` From 327c11768a4dbb60d0fd9bca3de3d073b8483012 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Thu, 17 Jul 2025 12:14:53 +1000 Subject: [PATCH 20/25] change(cli): Ansi constants to capitalised snake case --- cli/unstable_ansi.ts | 170 +++++++++++++++++++++---------------------- 1 file changed, 85 insertions(+), 85 deletions(-) diff --git a/cli/unstable_ansi.ts b/cli/unstable_ansi.ts index f5f0ef5ed74f..19e53704c406 100644 --- a/cli/unstable_ansi.ts +++ b/cli/unstable_ansi.ts @@ -17,8 +17,8 @@ * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_TOP + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_BOTTOM + "Hello World!"); * ``` * * @module @@ -27,7 +27,7 @@ /** * Causes content on the current line to enlarge, showing only the top half * of characters with each character taking up two columns. Can be used in - * combination with {@linkcode doubleHeightBottom} on the next line to + * combination with {@linkcode DOUBLE_HEIGHT_BOTTOM} on the next line to * make text appear twice as big. * * @returns The ANSI escape code for double-height top. @@ -36,16 +36,16 @@ * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_TOP + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_BOTTOM + "Hello World!"); * ``` */ -export const doubleHeightTop = "\x1b#3"; +export const DOUBLE_HEIGHT_TOP = "\x1b#3"; /** * Causes content on the current line to enlarge, showing only the bottom * half of the characters with each character taking up two columns. Can be - * used in combination with {@linkcode doubleHeightTop} on the previous + * used in combination with {@linkcode DOUBLE_HEIGHT_TOP} on the previous * line to make text appear twice as big. * * @returns The ANSI escape code for double-height bottom. @@ -54,16 +54,16 @@ export const doubleHeightTop = "\x1b#3"; * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_TOP + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_BOTTOM + "Hello World!"); * ``` */ -export const doubleHeightBottom = "\x1b#4"; +export const DOUBLE_HEIGHT_BOTTOM = "\x1b#4"; /** * Causes content on the current line to shrink down to a single column, - * essentially reverting the effects of {@linkcode doubleHeightTop}, - * {@linkcode doubleHeightBottom}, or {@linkcode doubleWidth}. + * essentially reverting the effects of {@linkcode DOUBLE_HEIGHT_TOP}, + * {@linkcode DOUBLE_HEIGHT_BOTTOM}, or {@linkcode DOUBLE_WIDTH}. * * @returns The ANSI escape code for single-width. * @@ -72,21 +72,21 @@ export const doubleHeightBottom = "\x1b#4"; * import { delay } from "@std/async/delay"; * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.doubleHeightTop + "Hello World!"); - * console.log(Ansi.doubleHeightBottom + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_TOP + "Hello World!"); + * console.log(Ansi.DOUBLE_HEIGHT_BOTTOM + "Hello World!"); * await delay(1000); * console.log( * Ansi.moveCursorUpStart(2) + * Ansi.deleteLines(1) + - * Ansi.singleWidth, + * Ansi.SINGLE_WIDTH, * ); * ``` */ -export const singleWidth = "\x1b#5"; +export const SINGLE_WIDTH = "\x1b#5"; /** * Causes content on the current line to stretch out, with each character - * taking up two columns. Can be reverted with {@linkcode singleWidth}. + * taking up two columns. Can be reverted with {@linkcode SINGLE_WIDTH}. * * @returns The ANSI escape code for double-width. * @@ -94,14 +94,14 @@ export const singleWidth = "\x1b#5"; * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.doubleWidth + "Hello World!"); + * console.log(Ansi.DOUBLE_WIDTH + "Hello World!"); * ``` */ -export const doubleWidth = "\x1b#6"; +export const DOUBLE_WIDTH = "\x1b#6"; /** * Saves current cursor position that can later be restored with - * {@linkcode restoreCursorPosition}. + * {@linkcode RESTORE_CURSOR_POSITION}. * * @returns The ANSI escape code for saving cursor position. * @@ -110,19 +110,19 @@ export const doubleWidth = "\x1b#6"; * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( - * Ansi.saveCursorPosition + + * Ansi.SAVE_CURSOR_POSITION + * Ansi.setCursorPosition(Deno.consoleSize().rows, 1) + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Hello World!" + - * Ansi.restoreCursorPosition, + * Ansi.RESTORE_CURSOR_POSITION, * ); * ``` */ -export const saveCursorPosition = "\x1b7"; +export const SAVE_CURSOR_POSITION = "\x1b7"; /** * Restores cursor position that was earlier saved with - * {@linkcode saveCursorPosition}. + * {@linkcode SAVE_CURSOR_POSITION}. * * @returns The ANSI escape code for restoring cursor position. * @@ -131,22 +131,22 @@ export const saveCursorPosition = "\x1b7"; * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( - * Ansi.saveCursorPosition + + * Ansi.SAVE_CURSOR_POSITION + * Ansi.setCursorPosition(Deno.consoleSize().rows) + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Hello World!" + - * Ansi.restoreCursorPosition, + * Ansi.RESTORE_CURSOR_POSITION, * ); * ``` */ -export const restoreCursorPosition = "\x1b8"; +export const RESTORE_CURSOR_POSITION = "\x1b8"; /** * This is a full reset of the terminal, reverting it back to its original * default settings, clearing the screen, resetting modes, colors, character * sets and more. Essentially making the terminal behave as if it were just * started by the user. This command is very disruptive to the user. Also see - * {@linkcode softReset}. + * {@linkcode SOFT_RESET}. * * @returns The ANSI escape code for hard resetting the terminal. * @@ -155,16 +155,16 @@ export const restoreCursorPosition = "\x1b8"; * import { delay } from "@std/async/delay"; * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.hideCursor); + * console.log(Ansi.HIDE_CURSOR); * await delay(5000); - * console.log(Ansi.hardReset); + * console.log(Ansi.HARD_RESET); * ``` */ -export const hardReset = "\x1bc"; +export const HARD_RESET = "\x1bc"; /** * This command resets many settings to their initial state without fully - * reinitializing the terminal like {@linkcode hardReset}. It preserves + * reinitializing the terminal like {@linkcode HARD_RESET}. It preserves * things like cursor position and display content, but clears modes, * character sets, etc. Should probably be called when exiting the program. * @@ -175,12 +175,12 @@ export const hardReset = "\x1bc"; * import { delay } from "@std/async/delay"; * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.hideCursor); + * console.log(Ansi.HIDE_CURSOR); * await delay(5000); - * console.log(Ansi.softReset); + * console.log(Ansi.SOFT_RESET); * ``` */ -export const softReset = "\x1b[!p"; +export const SOFT_RESET = "\x1b[!p"; /** * Inserts `x` spaces at the cursor position. Shifting existing line content @@ -366,7 +366,7 @@ export function moveCursorUpStart(x = 1): string { * "Goodbye" + * Ansi.moveCursorDown() + * Ansi.setCursorColumn() + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Bob!", * ); * ``` @@ -394,7 +394,7 @@ export function moveCursorDown(x = 1): string { * Ansi.moveCursorUpStart(2) + * "Goodbye" + * Ansi.moveCursorDownStart() + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Bob!", * ); * ``` @@ -517,7 +517,7 @@ export function setCursorColumn(x = 1): string { * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.setCursorLine() + Ansi.eraseLine + "Hello World!"); + * console.log(Ansi.setCursorLine() + Ansi.ERASE_LINE + "Hello World!"); * ``` */ export function setCursorLine(x = 1): string { @@ -538,7 +538,7 @@ export function setCursorLine(x = 1): string { * * console.log( * Ansi.setCursorPosition(5, 2) + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Hello World!", * ); * ``` @@ -563,11 +563,11 @@ export function setCursorPosition(x = 1, y = 1): string { * console.log( * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + - * Ansi.eraseLineAfterCursor, + * Ansi.ERASE_LINE_AFTER_CURSOR, * ); * ``` */ -export const eraseLineAfterCursor = "\x1b[0K"; +export const ERASE_LINE_AFTER_CURSOR = "\x1b[0K"; /** * Erases line content to the left of cursor position. @@ -585,11 +585,11 @@ export const eraseLineAfterCursor = "\x1b[0K"; * console.log( * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + - * Ansi.eraseLineBeforeCursor, + * Ansi.ERASE_LINE_BEFORE_CURSOR, * ); * ``` */ -export const eraseLineBeforeCursor = "\x1b[1K"; +export const ERASE_LINE_BEFORE_CURSOR = "\x1b[1K"; /** * Erases entire line content. @@ -603,10 +603,10 @@ export const eraseLineBeforeCursor = "\x1b[1K"; * * console.log("Hello World!"); * await delay(1000); - * console.log(Ansi.moveCursorUp() + Ansi.eraseLine); + * console.log(Ansi.moveCursorUp() + Ansi.ERASE_LINE); * ``` */ -export const eraseLine = "\x1b[2K"; +export const ERASE_LINE = "\x1b[2K"; /** * Erases content of lines below cursor position and content to the right on @@ -625,11 +625,11 @@ export const eraseLine = "\x1b[2K"; * console.log( * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + - * Ansi.eraseDisplayAfterCursor, + * Ansi.ERASE_DISPLAY_AFTER_CURSOR, * ); * ``` */ -export const eraseDisplayAfterCursor = "\x1b[0J"; +export const ERASE_DISPLAY_AFTER_CURSOR = "\x1b[0J"; /** * Erases content of lines above cursor position and content to the left on @@ -648,11 +648,11 @@ export const eraseDisplayAfterCursor = "\x1b[0J"; * console.log( * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + - * Ansi.eraseDisplayBeforeCursor, + * Ansi.ERASE_DISPLAY_BEFORE_CURSOR, * ); * ``` */ -export const eraseDisplayBeforeCursor = "\x1b[1J"; +export const ERASE_DISPLAY_BEFORE_CURSOR = "\x1b[1J"; /** * Erases all content. @@ -666,10 +666,10 @@ export const eraseDisplayBeforeCursor = "\x1b[1J"; * * console.log("Hello World!"); * await delay(1000); - * console.log(Ansi.eraseDisplay); + * console.log(Ansi.ERASE_DISPLAY); * ``` */ -export const eraseDisplay = "\x1b[2J"; +export const ERASE_DISPLAY = "\x1b[2J"; /** * Shifts content within the scrollable region up `x` lines, inserting blank @@ -728,7 +728,7 @@ export function repeatLastCharacter(x = 1): string { /** * Causes existing characters to the right of the cursor position to shift * right as new characters are written. Opposite of - * {@linkcode replaceMode}. + * {@linkcode REPLACE_MODE}. * * @returns The ANSI escape code for entering insert mode. * @@ -740,19 +740,19 @@ export function repeatLastCharacter(x = 1): string { * console.log("Hello World!"); * await delay(1000); * console.log( - * Ansi.insertMode + + * Ansi.INSERT_MODE + * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + * "and Goodbye " + - * Ansi.replaceMode, + * Ansi.REPLACE_MODE, * ); * ``` */ -export const insertMode = "\x1b[4h"; +export const INSERT_MODE = "\x1b[4h"; /** * Causes existing characters to be overwritten at the cursor position by new - * characters. See also {@linkcode insertMode}. + * characters. See also {@linkcode INSERT_MODE}. * * @returns The ANSI escape code for entering replace mode. * @@ -764,15 +764,15 @@ export const insertMode = "\x1b[4h"; * console.log("Hello World!"); * await delay(1000); * console.log( - * Ansi.insertMode + + * Ansi.INSERT_MODE + * Ansi.moveCursorUp() + * Ansi.setCursorColumn(7) + * "and Goodbye " + - * Ansi.replaceMode, + * Ansi.REPLACE_MODE, * ); * ``` */ -export const replaceMode = "\x1b[4l"; +export const REPLACE_MODE = "\x1b[4l"; /** * Causes top and bottom margins to shrink to scrollable region (See @@ -787,21 +787,21 @@ export const replaceMode = "\x1b[4l"; * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( - * Ansi.eraseDisplay + + * Ansi.ERASE_DISPLAY + * Ansi.setCursorPosition() + * "Hello World" + * Ansi.setScrollableRegion(2) + - * Ansi.enableOriginMode, + * Ansi.ENABLE_ORIGIN_MODE, * ); * await delay(1000); * console.log(Ansi.setCursorPosition() + "Bye World!"); * ``` */ -export const enableOriginMode = "\x1b[?6h"; +export const ENABLE_ORIGIN_MODE = "\x1b[?6h"; /** * Causes the top and bottom margins to enlarge to the user's display. See - * {@linkcode enableOriginMode}. + * {@linkcode ENABLE_ORIGIN_MODE}. * * @returns The ANSI escape code for disabling origin mode. * @@ -811,29 +811,29 @@ export const enableOriginMode = "\x1b[?6h"; * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( - * Ansi.eraseDisplay + + * Ansi.ERASE_DISPLAY + * Ansi.setCursorPosition() + * "Hello World" + * Ansi.setScrollableRegion(2) + - * Ansi.enableOriginMode, + * Ansi.ENABLE_ORIGIN_MODE, * ); * await delay(1000); * console.log(Ansi.setCursorPosition() + "Bye World!"); * await delay(1000); * console.log( - * Ansi.disableOriginMode + + * Ansi.DISABLE_ORIGIN_MODE + * Ansi.setCursorPosition() + - * Ansi.eraseLine + + * Ansi.ERASE_LINE + * "Hi World!", * ); * ``` */ -export const disableOriginMode = "\x1b[?6l"; +export const DISABLE_ORIGIN_MODE = "\x1b[?6l"; /** * Causes cursor to automatically move to the next line when it hits the * end of the current line to continue writing. See also - * {@linkcode disableAutoWrap}. + * {@linkcode DISABLE_AUTO_WRAP}. * * @returns The ANSI escape code to enable auto-wrap. * @@ -841,14 +841,14 @@ export const disableOriginMode = "\x1b[?6l"; * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.enableAutoWrap + "A" + "h".repeat(500)); + * console.log(Ansi.ENABLE_AUTO_WRAP + "A" + "h".repeat(500)); * ``` */ -export const enableAutoWrap = "\x1b[?7h"; +export const ENABLE_AUTO_WRAP = "\x1b[?7h"; /** * Causes cursor to remain on the same line when it hits the end of the - * current line. See also {@linkcode enableAutoWrap}. + * current line. See also {@linkcode ENABLE_AUTO_WRAP}. * * @returns The ANSI escape code to disable auto-wrap. * @@ -856,10 +856,10 @@ export const enableAutoWrap = "\x1b[?7h"; * ```ts ignore * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.disableAutoWrap + "A" + "h".repeat(500)); + * console.log(Ansi.DISABLE_AUTO_WRAP + "A" + "h".repeat(500)); * ``` */ -export const disableAutoWrap = "\x1b[?7l"; +export const DISABLE_AUTO_WRAP = "\x1b[?7l"; /** * Sets the cursor animation style. @@ -880,7 +880,7 @@ export function setCursorStyle(x: CursorStyle): string { /** * Causes cursor position to be visible to the user. See also - * {@linkcode hideCursor}. + * {@linkcode HIDE_CURSOR}. * * @returns The ANSI escape code to show the cursor. * @@ -889,16 +889,16 @@ export function setCursorStyle(x: CursorStyle): string { * import { delay } from "@std/async/delay"; * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.hideCursor); + * console.log(Ansi.HIDE_CURSOR); * await delay(5000); - * console.log(Ansi.showCursor); + * console.log(Ansi.SHOW_CURSOR); * ``` */ -export const showCursor = "\x1b[?25h"; +export const SHOW_CURSOR = "\x1b[?25h"; /** * Causes cursor position to be hidden from the user. See also - * {@linkcode showCursor}. + * {@linkcode SHOW_CURSOR}. * * @returns The ANSI escape code to hide the cursor. * @@ -907,12 +907,12 @@ export const showCursor = "\x1b[?25h"; * import { delay } from "@std/async/delay"; * import * as Ansi from "@std/cli/unstable-ansi"; * - * console.log(Ansi.hideCursor); + * console.log(Ansi.HIDE_CURSOR); * await delay(5000); - * console.log(Ansi.showCursor); + * console.log(Ansi.SHOW_CURSOR); * ``` */ -export const hideCursor = "\x1b[?25l"; +export const HIDE_CURSOR = "\x1b[?25l"; /** * Sets the scrollable region of the display. Allowing either or both the top @@ -929,7 +929,7 @@ export const hideCursor = "\x1b[?25l"; * import * as Ansi from "@std/cli/unstable-ansi"; * * console.log( - * Ansi.eraseDisplay + + * Ansi.ERASE_DISPLAY + * Ansi.setScrollableRegion(3, 10), * ); * setInterval(() => console.log(Math.random()), 1000); From 907208cd568ceb5a3bea404ac424f48f231fe716 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Sat, 19 Jul 2025 11:51:36 +1000 Subject: [PATCH 21/25] update(cli): static line code to match ansi branch --- cli/unstable_static_line.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 26c7168a895f..ff127bd63661 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -92,17 +92,17 @@ export class StaticLine { async write(line: string): Promise { if (this.#released) throw new ReferenceError("Line has been released"); await write( - Ansi.saveCursorPosition + - Ansi.disableAutoWrap + + Ansi.SAVE_CURSOR_POSITION + + Ansi.DISABLE_AUTO_WRAP + Ansi.setCursorPosition( this.#atTop ? linesAtTop.indexOf(this.#id) + 1 : getRows() - linesAtBottom.indexOf(this.#id), ) + - Ansi.eraseLine + + Ansi.ERASE_LINE + line + - Ansi.enableAutoWrap + - Ansi.restoreCursorPosition, + Ansi.ENABLE_AUTO_WRAP + + Ansi.RESTORE_CURSOR_POSITION, ); } @@ -137,7 +137,7 @@ export class StaticLine { const top = linesAtTop.length + 1; const bottom = rows - linesAtBottom.length; await write( - Ansi.saveCursorPosition + + Ansi.SAVE_CURSOR_POSITION + (this.#atTop ? Ansi.setScrollableRegion(index + 1, top + 1) + Ansi.shiftUpAndInsert() @@ -148,9 +148,9 @@ export class StaticLine { ) + Ansi.shiftDownAndInsert() : Ansi.setCursorPosition(rows) + - Ansi.eraseLine)) + + Ansi.ERASE_LINE)) + Ansi.setScrollableRegion(top, bottom) + - Ansi.restoreCursorPosition, + Ansi.RESTORE_CURSOR_POSITION, ); } } From 3efac67e6268e97d05bdb0ce511ebbb250977d4e Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:03:07 +1000 Subject: [PATCH 22/25] change(cli): param from `atTop` to `on` --- cli/unstable_static_line.ts | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index ff127bd63661..8d93452b9b62 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -50,17 +50,16 @@ export class StaticLine { /** * Constructs a new instance. * - * @param atTop Whether the line should be at the top or bottom of the - * terminal. + * @param on What side of the terminal the line should be on. */ - constructor(atTop = false) { - this.#atTop = atTop; - this.#lines = atTop ? linesAtTop : linesAtBottom; + constructor(on: "top" | "bottom" = "bottom") { + this.#atTop = on === "top"; + this.#lines = this.#atTop ? linesAtTop : linesAtBottom; this.#lines.push(this.#id); const top = linesAtTop.length + 1; const bottom = getRows() - linesAtBottom.length; write( - (atTop ? "" : Ansi.shiftUpAndInsert()) + + (this.#atTop ? "" : Ansi.shiftUpAndInsert()) + Ansi.setScrollableRegion(top, bottom) + Ansi.setCursorPosition(bottom), ); From e12d57d06c4dcbd4b129fa6dbf0ec8ee01bd3970 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:03:56 +1000 Subject: [PATCH 23/25] fix(cli): behaviour for releasing lines --- cli/unstable_static_line.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 8d93452b9b62..f35ed4c5b9d6 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -138,9 +138,12 @@ export class StaticLine { await write( Ansi.SAVE_CURSOR_POSITION + (this.#atTop - ? Ansi.setScrollableRegion(index + 1, top + 1) + - Ansi.shiftUpAndInsert() - : (linesAtBottom.length + ? (top - index + ? Ansi.setScrollableRegion(index + 1, top + 1) + + Ansi.shiftUpAndInsert() + : Ansi.setCursorPosition(index + 1) + + Ansi.ERASE_LINE) + : (rows - index - bottom ? Ansi.setScrollableRegion( bottom, rows - index, From 32d7d6e137cdfeac2a28f37dd0d3842f0ffd76fd Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Sun, 20 Jul 2025 11:04:26 +1000 Subject: [PATCH 24/25] fix(cli): behaviour for writing lines --- cli/unstable_static_line.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index f35ed4c5b9d6..34a4198c65b4 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -92,6 +92,7 @@ export class StaticLine { if (this.#released) throw new ReferenceError("Line has been released"); await write( Ansi.SAVE_CURSOR_POSITION + + Ansi.DISABLE_ORIGIN_MODE + Ansi.DISABLE_AUTO_WRAP + Ansi.setCursorPosition( this.#atTop @@ -100,7 +101,6 @@ export class StaticLine { ) + Ansi.ERASE_LINE + line + - Ansi.ENABLE_AUTO_WRAP + Ansi.RESTORE_CURSOR_POSITION, ); } From 1caadfbfa2a2b06d698e169652e2da871f5198b8 Mon Sep 17 00:00:00 2001 From: BlackAsLight <44320105+BlackAsLight@users.noreply.github.com> Date: Tue, 22 Jul 2025 13:09:13 +1000 Subject: [PATCH 25/25] fix(cli): error due to changes made in ansi --- cli/unstable_static_line.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/unstable_static_line.ts b/cli/unstable_static_line.ts index 34a4198c65b4..4adbe7358943 100644 --- a/cli/unstable_static_line.ts +++ b/cli/unstable_static_line.ts @@ -91,7 +91,7 @@ export class StaticLine { async write(line: string): Promise { if (this.#released) throw new ReferenceError("Line has been released"); await write( - Ansi.SAVE_CURSOR_POSITION + + Ansi.SAVE_CURSOR + Ansi.DISABLE_ORIGIN_MODE + Ansi.DISABLE_AUTO_WRAP + Ansi.setCursorPosition( @@ -101,7 +101,7 @@ export class StaticLine { ) + Ansi.ERASE_LINE + line + - Ansi.RESTORE_CURSOR_POSITION, + Ansi.RESTORE_CURSOR, ); } @@ -136,7 +136,7 @@ export class StaticLine { const top = linesAtTop.length + 1; const bottom = rows - linesAtBottom.length; await write( - Ansi.SAVE_CURSOR_POSITION + + Ansi.SAVE_CURSOR + (this.#atTop ? (top - index ? Ansi.setScrollableRegion(index + 1, top + 1) + @@ -152,7 +152,7 @@ export class StaticLine { : Ansi.setCursorPosition(rows) + Ansi.ERASE_LINE)) + Ansi.setScrollableRegion(top, bottom) + - Ansi.RESTORE_CURSOR_POSITION, + Ansi.RESTORE_CURSOR, ); } }