-
Notifications
You must be signed in to change notification settings - Fork 0
API Terminal
picocalc.terminal provides a full-featured terminal emulator widget. Each terminal has its own cell grid, scrollback buffer, cursor, and colour state. Multiple terminals can be created but only one should render to the display at a time.
local term = picocalc.terminal.new([cols [, rows [, scrollback]]])-
cols(number, default 53): grid width in characters -
rows(number, default 26): grid height in characters -
scrollback(number, default 1000): number of lines kept in scrollback history
Returns a terminal object. Raises an error if allocation fails (PSRAM OOM).
-- Full-screen terminal with default size
local term = picocalc.terminal.new()
-- Smaller terminal, 500-line scrollback
local term = picocalc.terminal.new(40, 20, 500)Write a string to the terminal at the current cursor position. Supports ANSI escape sequences (cursor movement, colour codes, erase sequences, etc.). The cursor advances automatically; lines wrap and the display scrolls when the bottom row is reached.
term:write("Hello, world!\n")
term:write("\27[31mRed text\27[0m\n") -- ANSI colourClear all cells and reset the cursor to (0, 0).
Move the cursor to column x, row y (0-based).
Return the current cursor column and row (0-based).
Show or hide the cursor.
Enable or disable cursor blinking.
Set the default foreground and background colours (RGB565).
Return the current default foreground and background colours.
Scroll the viewport up by lines rows (positive = up, negative = down).
Return the number of lines currently in the scrollback buffer.
Return scrollback line n (1-based) as a plain string. Raises an error if n is out of range.
Return the current scrollback view offset (0 = showing live output).
Jump the viewport to a specific scrollback position.
Call one of these once per frame after writing content.
Redraw every cell to the framebuffer. Use when the whole screen may be stale (e.g. first frame, font change).
Redraw only rows marked dirty since the last render. Faster than render() for incremental updates.
Mark every row as dirty so the next renderDirty() redraws everything.
Returns true if all rows are marked dirty.
Return the first and last dirty row indices (inclusive). Useful for partial redraws.
Switch the terminal font. Valid values:
| Name | Description |
|---|---|
"scientifica" |
Default bitmap font |
"scientifica_bold" |
Bold variant |
Return the current font name string.
Draw a gutter on the left side with line numbers.
Enable or disable the line number gutter (default: off).
Set the first line number displayed (default: 1).
Set the gutter width in columns (default: 5).
Set gutter foreground and background colours (RGB565).
Return the number of columns available for content (terminal cols − gutter width). Use this when calculating text layout so content does not overlap the gutter.
term:setLineNumbers(true)
term:setLineNumberCols(4)
term:setLineNumberColors(0x7BEF, 0x2945) -- grey on dark
local usable = term:getContentCols() -- e.g. 49 when gutter is 4Draw a vertical scrollbar on the right side.
Enable or disable the scrollbar (default: off).
Set the scrollbar track background and thumb colours (RGB565).
Set the scrollbar width in pixels (default: 4).
Tell the scrollbar how many total logical lines exist and where the current viewport starts. Call this each frame when the document length or scroll position changes.
term:setScrollbar(true)
term:setScrollbarWidth(6)
term:setScrollInfo(#lines, scroll_offset)Return the total number of columns in the terminal grid.
Return the total number of rows in the terminal grid.
Restrict rendering to rows between y_start and y_end (inclusive). Useful for embedding a terminal in a portion of the screen alongside other UI elements.
-
y_start(number): First row to render (0-based pixel row) -
y_end(number): Last row to render
term:setRenderBounds(16, 300) -- leave room for a headerDirect cell manipulation for syntax highlighting and custom rendering.
Set the character at column x, row y (0-based). Out-of-bounds coordinates are silently ignored.
-
x(number): Column -
y(number): Row -
ch(string): Single character to place in the cell
Return the character at column x, row y as a single-character string. Returns " " for out-of-bounds coordinates or empty cells.
Set the foreground and background colours (RGB565) of a single cell. Marks the row dirty.
-
x(number): Column -
y(number): Row -
fg(number): Foreground colour (RGB565) -
bg(number): Background colour (RGB565)
Batch-set foreground and background colours for a range of cells in row y. Both fgTable and bgTable are arrays of RGB565 values. Marks the row dirty.
-
y(number): Row -
fgTable(table): Array of foreground colours -
bgTable(table): Array of background colours -
startX(number, optional): Starting column (default 0) -
count(number, optional): Number of cells to set (default: all columns)
-- Highlight columns 0-9 of row 3
local fg = {}; local bg = {}
for i = 1, 10 do fg[i] = 0xFFE0; bg[i] = 0x0000 end -- yellow on black
term:setRowColors(3, fg, bg, 0, 10)Enable or disable word wrapping (default: off).
Set the column at which wrapping occurs.
Show a visual indicator (e.g. ↩) at wrapped line ends.
Return the current word-wrap state.
Return the number of visual (wrapped) rows the current content occupies.
These methods block the calling Lua coroutine while keeping the system menu, HTTP callbacks, screenshots, and the watchdog all responsive.
Block until any button is pressed, then return nil.
Block until the named key is pressed. Returns the button mask integer.
Valid key names: "enter", "left", "right", "up", "down", "esc", "f1"–"f5", "tab", "backspace".
Non-blocking. Returns the button mask if any key is currently pressed, or nil.
Non-blocking. Returns a single-character string if a printable key was typed, or nil.
Block until a printable character is typed. Returns the character as a string.
local D = picocalc.display
local term = picocalc.terminal.new()
term:setLineNumbers(true)
term:setScrollbar(true)
term:setScrollbarWidth(6)
local lines = {}
local function redraw()
term:renderDirty()
D.flush()
end
-- Write some content
for i = 1, 50 do
local line = string.format("Line %d: the quick brown fox\n", i)
table.insert(lines, line)
term:write(line)
end
term:setScrollInfo(#lines, 0)
redraw()
-- Scroll with arrow keys
while true do
local key = term:waitForKey("up") or term:readKey()
if key then
if key & picocalc.input.BTN_UP ~= 0 then
term:scroll(-1)
elseif key & picocalc.input.BTN_DOWN ~= 0 then
term:scroll(1)
elseif key & picocalc.input.BTN_ESC ~= 0 then
return
end
redraw()
end
end