Skip to content

Commit

Permalink
add workdflow
Browse files Browse the repository at this point in the history
  • Loading branch information
zhangfuxing committed Nov 18, 2024
1 parent f1d3e6b commit 918b8c3
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 4 deletions.
19 changes: 19 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Publish
on:
push:
branches:
- main

jobs:
publish:
runs-on: ubuntu-latest

permissions:
contents: read
id-token: write

steps:
- uses: actions/checkout@v4

- name: Publish package
run: npx jsr publish
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Termbox is a deno package that provides a cell based view for text terminals.
## Usage

```ts
import TermBox from "jsr:deno-library/termbox";
import TermBox from "jsr:@deno-library/termbox";
// or
// import TermBox from "https://deno.land/x/[email protected].0/mod.ts";
// import TermBox from "https://deno.land/x/[email protected].1/mod.ts";

const termbox = new TermBox();

Expand Down
2 changes: 1 addition & 1 deletion deno.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@deno-library/termbox",
"version": "0.2.0",
"version": "0.2.1",
"exports": "./mod.ts"
}
103 changes: 102 additions & 1 deletion mod.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* Constants for ANSI escape sequences.
*/
const ESC = "\x1B[";

const SAVE = "\x1B7"; // "\x1B[s"
Expand All @@ -12,18 +15,47 @@ const HOME = "H";

const isTTY = Deno.stdout.isTerminal;

/**
* Interface representing the size of the terminal.
*/
interface Size {
columns: number;
rows: number;
}

/**
* A class for managing terminal operations using ANSI escape sequences.
*/
export default class TermBox {
/**
* Encoder for converting strings to Uint8Array.
*/
private encoder = new TextEncoder();

/**
* Writer for writing to the terminal.
*/
private writer = Deno.stdout.writable.getWriter();

/**
* Two-dimensional array representing the terminal cells.
*/
private cells: string[][];

/**
* Number of columns in the terminal.
*/
private columns: number;

/**
* Number of rows in the terminal.
*/
private rows: number;

/**
* Constructs a new TermBox instance.
* @param size Optional size of the terminal. If not provided, it will be determined automatically.
*/
constructor(size?: Size) {
const { columns, rows } = size ?? this.size();
this.columns = columns;
Expand All @@ -33,19 +65,39 @@ export default class TermBox {
.map(() => new Array(columns).fill(null).map(() => " "));
}

/**
* Moves the cursor to a specified position.
* @param action The ANSI escape sequence for cursor movement.
* @returns A promise that resolves when the operation is complete.
*/
private cursor(action: string): Promise<void> {
return this.write(ESC + action);
}

/**
* Writes a message to the terminal.
* @param msg The message to write.
* @returns A promise that resolves when the operation is complete.
*/
private write(msg: string): Promise<void> {
return this.writer.write(this.encoder.encode(msg));
}

/**
* Flushes the current state of the terminal cells to the terminal.
* @returns A promise that resolves when the operation is complete.
*/
async flush(): Promise<void> {
await this.cursorTo(0, 0);
return this.write(this.cells.map((v) => v.join("")).join("\n"));
}

/**
* Sets the content of a specific cell in the terminal grid.
* @param x The column index.
* @param y The row index.
* @param char The character to set.
*/
setCell(x: number, y: number, char: string): void {
if (x >= this.columns || x < 0) return;
if (y >= this.rows || y < 0) return;
Expand All @@ -55,26 +107,52 @@ export default class TermBox {
this.cells[y][x] = char;
}

/**
* Hides the cursor.
* @returns A promise that resolves when the operation is complete.
*/
cursorHide(): Promise<void> {
return this.cursor(HIDE);
}

/**
* Shows the cursor.
* @returns A promise that resolves when the operation is complete.
*/
cursorShow(): Promise<void> {
return this.cursor(SHOW);
}

/**
* Saves the current cursor position.
* @returns A promise that resolves when the operation is complete.
*/
cursorSave(): Promise<void> {
return this.write(SAVE);
}

/**
* Restores the saved cursor position.
* @returns A promise that resolves when the operation is complete.
*/
cursorRestore(): Promise<void> {
return this.write(RESTORE);
}

/**
* Moves the cursor to a specific position.
* @param x The column index.
* @param y The row index.
* @returns A promise that resolves when the operation is complete.
*/
cursorTo(x: number, y: number): Promise<void> {
return this.cursor(`${y};${x}${HOME}`);
}

/**
* Gets the current cursor position.
* @returns A promise that resolves with the cursor position.
*/
async cursorPosition(): Promise<Size> {
if (!isTTY) {
return { columns: 0, rows: 0 };
Expand All @@ -101,14 +179,26 @@ export default class TermBox {
}
}

/**
* Clears the screen.
* @returns A promise that resolves when the operation is complete.
*/
screenClear(): Promise<void> {
return this.cursor(CLEAR_SCREEN);
}

/**
* Resets the screen to its initial state.
* @returns A promise that resolves when the operation is complete.
*/
screenReset(): Promise<void> {
return this.write(ESC + (this.rows - 1) + "A\r\x1b[?0J");
}

/**
* Gets the size of the terminal.
* @returns The size of the terminal.
*/
size(): Size {
if (!isTTY) return { columns: 100, rows: 50 };
return {
Expand All @@ -117,11 +207,17 @@ export default class TermBox {
};
}

/**
* Ends the session and releases any resources.
*/
end(): void {
this.writer.releaseLock();
}
}

/**
* Regular expression pattern for matching ANSI escape codes.
*/
// https://github.com/chalk/ansi-regex/blob/02fa893d619d3da85411acc8fd4e2eea0e95a9d9/index.js
const ANSI_PATTERN = new RegExp(
[
Expand All @@ -131,6 +227,11 @@ const ANSI_PATTERN = new RegExp(
"g",
);

/**
* Strips ANSI escape codes from a string.
* @param string The string to strip.
* @returns The stripped string.
*/
function stripAnsiCode(string: string): string {
return string.replace(ANSI_PATTERN, "");
}
}

0 comments on commit 918b8c3

Please sign in to comment.