screen API reference
Terminal user interfaces: an explicit screen, not a GUI framework. Two layers. The output-only layer is pure strings over ANSI control sequences - a cell Buffer you draw into (text / box / fill) and paint with render, plus diff for a flicker-free update loop (dashboards, progress, self-updating tables); it needs no host capability and runs on both binaries. The interactive layer decodes a raw byte stream into Key events (decodeKey, pure and testable) and drives an event loop over the term library's raw mode (begin / nextKey / end) for menus, forms, and key navigation; that layer needs term, so it works on the default jennifer (a friendly error on jennifer-tiny, which stubs term).
Coordinates are 0-based with the origin at the top-left (0, 0); x is the column, y the row. Drawing that runs past an edge is clipped, not an error.
Import with import "screen.j" as screen;. See the screen guide for prose and examples.
Functions
screen.begin()
Enter full-screen interactive mode: put the terminal in raw mode and switch to the alternate screen with the cursor hidden and the screen cleared. Pair with end, ideally via defer screen.end($state);. Requires the term library (default binary).
Returns {term.State} - the raw-mode handle to pass to end
screen.box(buf as Buffer, x as int, y as int, w as int, h as int)
A copy of buf with a single-line box border drawn at (x, y) of outer size w by h, using Unicode box-drawing glyphs. The interior is untouched.
Parameters
buf{Buffer}- the source bufferx{int}- the left column (0-based)y{int}- the top row (0-based)w{int}- the outer width in columns (>= 2)h{int}- the outer height in rows (>= 2)
Returns {Buffer} - the updated buffer
screen.clear()
The sequence that clears the whole screen and homes the cursor.
Returns {string} - the clear-screen escape sequence
screen.clearBuffer(buf as Buffer)
A copy of buf with every cell reset to a space.
Parameters
buf{Buffer}- the source buffer
Returns {Buffer} - the cleared buffer
screen.clearLine()
The sequence that clears the current line.
Returns {string} - the clear-line escape sequence
screen.decodeKey(seq as list of int)
Decode one raw key byte sequence into a Key. Pure and total: seq is the bytes of a single key press ([65] for A, [27, 91, 65] for Up, [27, 91, 51, 126] for Delete). Unrecognized input decodes to "unknown"; an empty sequence to "eof". This is what nextKey calls after reading the bytes, exposed separately so key handling is testable without a terminal.
Parameters
seq{list of int}- the raw byte values of one key event
Returns {Key} - the decoded key
screen.diff(old as Buffer, new as Buffer)
The minimal escape string that turns the terminal showing old into new - only the changed cells are repositioned and rewritten, in row runs. When the two buffers differ in size it falls back to a full render(new). This is the flicker-free update path: keep the previous buffer, diff against the next.
Parameters
old{Buffer}- the buffer currently on screennew{Buffer}- the buffer to display
Returns {string} - the minimal-update escape string
screen.down(n as int)
The sequence that moves the cursor down n rows.
Parameters
n{int}- the number of rows
Returns {string} - the cursor-down escape sequence
screen.end(state as term.State)
Leave interactive mode: show the cursor, leave the alternate screen, and restore the terminal from the handle begin returned.
Parameters
state{term.State}- the handle returned bybegin
Returns {null} - nothing
screen.enterAlt()
The sequence that switches to the alternate screen buffer (so the app's output does not scroll the user's shell history).
Returns {string} - the enter-alternate-screen escape sequence
screen.exitAlt()
The sequence that leaves the alternate screen buffer, restoring the prior terminal contents.
Returns {string} - the leave-alternate-screen escape sequence
screen.fill(buf as Buffer, x as int, y as int, w as int, h as int, ch as string)
A copy of buf with the rectangle at (x, y) of size w by h filled with the glyph ch. Clipped to the buffer.
Parameters
buf{Buffer}- the source bufferx{int}- the left column (0-based)y{int}- the top row (0-based)w{int}- the width in columnsh{int}- the height in rowsch{string}- the fill glyph (one column)
Returns {Buffer} - the updated buffer
screen.get(buf as Buffer, x as int, y as int)
The contents of the cell at (x, y), or an empty string if out of range.
Parameters
buf{Buffer}- the bufferx{int}- the column (0-based)y{int}- the row (0-based)
Returns {string} - the cell contents
screen.hideCursor()
The sequence that hides the text cursor.
Returns {string} - the hide-cursor escape sequence
screen.hline(buf as Buffer, x as int, y as int, n as int, ch as string)
A copy of buf with a horizontal line of n cells of ch from (x, y).
Parameters
buf{Buffer}- the source bufferx{int}- the starting column (0-based)y{int}- the row (0-based)n{int}- the length in columnsch{string}- the line glyph (one column)
Returns {Buffer} - the updated buffer
screen.home()
The sequence that homes the cursor to the top-left.
Returns {string} - the cursor-home escape sequence
screen.left(n as int)
The sequence that moves the cursor left n columns.
Parameters
n{int}- the number of columns
Returns {string} - the cursor-back escape sequence
screen.moveTo(x as int, y as int)
The sequence that moves the cursor to (x, y) (0-based; origin top-left).
Parameters
x{int}- the target column (0-based)y{int}- the target row (0-based)
Returns {string} - the cursor-position escape sequence
screen.newScreen(rows as int, cols as int)
A new blank Buffer of rows by cols cells, every cell a space.
Parameters
rows{int}- the number of rows (must be positive)cols{int}- the number of columns (must be positive)
Returns {Buffer} - the blank buffer
Throws
{Error}- whenrowsorcolsis not positive
screen.nextKey()
Read and decode the next key from the terminal (blocking). Reads raw bytes through the term library, assembling a full escape sequence before decoding, and returns the Key. At end of input the name is "eof". Requires raw mode (see begin) and the term library (default binary).
A lone Escape press is only reported once the next byte arrives, because term.readByte has no timeout to distinguish it from the start of an escape sequence; prefer a named key (or Ctrl-C) to quit an event loop.
Returns {Key} - the next key event
screen.render(buf as Buffer)
The escape string that paints the whole buf to the terminal (positions the cursor at the start of each row and writes its cells). Print it with io.printf; usually preceded once by clear.
Parameters
buf{Buffer}- the buffer to paint
Returns {string} - the full-repaint escape string
screen.right(n as int)
The sequence that moves the cursor right n columns.
Parameters
n{int}- the number of columns
Returns {string} - the cursor-forward escape sequence
screen.set(buf as Buffer, x as int, y as int, cell as string)
A copy of buf with the single cell at (x, y) set to cell (one column). Out-of-range coordinates are clipped (returns buf unchanged).
Parameters
buf{Buffer}- the source bufferx{int}- the column (0-based)y{int}- the row (0-based)cell{string}- the cell contents (one visible column)
Returns {Buffer} - the updated buffer
screen.showCursor()
The sequence that shows the text cursor.
Returns {string} - the show-cursor escape sequence
screen.size()
The terminal size as a term.Size ({rows, cols}), a convenience passthrough to term.size so an app stays in one namespace. Requires the term library.
Returns {term.Size} - the terminal dimensions
screen.text(buf as Buffer, x as int, y as int, s as string)
A copy of buf with s written left-to-right starting at (x, y), one rune per cell, clipped at the row's right edge (no wrapping).
Parameters
buf{Buffer}- the source bufferx{int}- the starting column (0-based)y{int}- the row (0-based)s{string}- the text to write
Returns {Buffer} - the updated buffer
screen.textColor(buf as Buffer, x as int, y as int, s as string, color as string)
A copy of buf with s written from (x, y) in the named foreground colour, one rune per cell, clipped at the row's right edge.
Parameters
buf{Buffer}- the source bufferx{int}- the starting column (0-based)y{int}- the row (0-based)s{string}- the text to writecolor{string}- the colour name (e.g."red","cyan")
Returns {Buffer} - the updated buffer
Throws
{Error}- whencoloris not a known colour
screen.up(n as int)
The sequence that moves the cursor up n rows.
Parameters
n{int}- the number of rows
Returns {string} - the cursor-up escape sequence
screen.vline(buf as Buffer, x as int, y as int, n as int, ch as string)
A copy of buf with a vertical line of n cells of ch from (x, y).
Parameters
buf{Buffer}- the source bufferx{int}- the column (0-based)y{int}- the starting row (0-based)n{int}- the length in rowsch{string}- the line glyph (one column)
Returns {Buffer} - the updated buffer
Structs
screen.Buffer
A rectangular grid of character cells, drawn into then painted to the terminal. cells is row-major (y * cols + x); each cell is a one-column string, optionally wrapped in an SGR colour sequence. Value-semantic like any struct: the drawing functions return a fresh Buffer.
| Field | Type | Description |
|---|---|---|
rows | int | the number of rows (height) |
cols | int | the number of columns (width) |
cells | list of string | row-major cell contents, length rows * cols |
screen.Key
A decoded key event from nextKey / decodeKey. name is a symbolic key name: a printable key is "char" (with the character in char); the rest are named - "up" / "down" / "left" / "right", "enter" / "tab" / "escape" / "backspace" / "delete" / "insert", "home" / "end" / "pageup" / "pagedown", "f1".."f12", "ctrl-a".."ctrl-z", "alt-<c>", "eof" at end of input, and "unknown".
| Field | Type | Description |
|---|---|---|
name | string | the symbolic key name |
char | string | the character for a "char" / "alt-" key, else empty |