std/term
Colors and styles
print(paint("error:", "bold red"), "file not found")
print(paint("note", "italic #ff8800 on_#202020"))
print(success("Saved"), warning("Low disk space"))| Function | Result |
|---|---|
paint(text, style) |
text in a style: words separated by spaces |
bold, dim, italic, underline (text) |
shortcuts for one style |
red, green, yellow, blue, magenta, cyan, gray (text) |
shortcuts for one color |
rgb(r, g, b) |
a color word such as #ff8800, for paint |
link(text, url) |
a clickable link in terminals that support them |
success, failure, warning, info (text) |
text after a colored ✔, ✖, ⚠, or ℹ |
strip_styles(text) |
text without any terminal codes |
set_color(on) |
turns colors on or off whatever the output is |
color_enabled() |
whether colors are in use |
Style words are bold, dim, italic, underline, blink, inverse,
hidden, and strike; the colors black, red, green, yellow, blue,
magenta, cyan, white, gray, and bright_ forms such as
bright_red; hex colors such as #ff8800; and any color with on_ for the
background. An unknown word stops the program with a message, so a typo is
found at once. Styles nest: a painted piece inside painted text keeps its
own style, and the outer style returns after it.
Colors are used when standard output is a terminal, unless the NO_COLOR
variable is set or TERM is dumb; FORCE_COLOR turns them on.
set_color overrides all of that. Without colors every function returns
plain text, so output sent to a file or another program stays clean.
The cursor and the screen
Each of these returns the code to write, or "" when output is not a
terminal:
| Function | Moves or clears |
|---|---|
cursor_up, cursor_down, cursor_left, cursor_right (n) |
the cursor by n |
cursor_to(row, column) |
the cursor to a place, counted from 1 |
cursor_column(column) |
the cursor to a column of its line |
hide_cursor(), show_cursor() |
the cursor's visibility |
clear_line() |
the current line, moving to its start |
clear_below() |
from the cursor to the end of the screen |
clear_screen() |
everything, moving to the top |
controls_enabled() says whether these codes are in use: on a terminal they
are, even when NO_COLOR turns colors off.
enter_screen() switches to the terminal's second screen, as editors and
games do, and hides the cursor; leave_screen() brings back the normal
screen as it was. If the program ends first, even by a runtime error, the
normal screen comes back anyway.
Measuring and laying out text
print(box(["Cuarzo 1.0", "ready"], "welcome"))
print(table(["name", "stars"], [["cuarzo", "★★★"], ["seed", "★"]]))
print(progress_bar(0.42, 20))std/term passes on std/text, so text_width, pad_right,
truncate, wrap, and the rest of its measuring and laying out come with
it.
| Function | Result |
|---|---|
columns(items, width) |
items in columns, as ls lists files |
rule(width) |
a horizontal line |
box(lines, title) |
lines in a box with rounded corners |
table(header, rows) |
rows in aligned columns under a bold header |
progress_bar(fraction, width) |
a bar filled from 0 to 1, with the percent |
spinner_frame(frame) |
one frame of a spinner, for frames 0, 1, 2, ... |
Events, screens, and frames
Full-screen programs read every event of the terminal, draw on a Screen
of cells that writes only what changed, and run at a steady number of
frames a second:
import "std/term"
enter_screen()
Screen s = screen(terminal_width(), terminal_height())
f64 x = 10.0
run_frames(30, func(TermEvent e) bool do
if e.kind == "resize" then
screen_resize(s, e.width, e.height)
end
return not (e.kind == "key" and e.key == "q")
end, func(f64 seconds) bool do
if key_down("right") then
x += 20.0 * seconds
end
screen_clear(s)
screen_text(s, int(x), 2, "▶", "bold green")
screen_flush(s)
return true
end)
stop_events()
leave_screen()| Function | Result |
|---|---|
read_event(wait_ms) |
the next TermEvent, waiting up to wait_ms milliseconds, or for ever below 0; kind "none" when none came |
key_down(name) |
whether a key, named as events name keys, is held now |
key_events_supported() |
whether the terminal reports releases: always on Windows, and elsewhere where it has the kitty keyboard protocol |
mouse_mode(on) |
turns the reporting of clicks, drags, motion, and the wheel on or off |
stop_events() |
leaves the mode read_event puts the terminal in; the end of the program leaves it too |
screen(width, height), screen_resize(s, width, height) |
a Screen of cells, drawn from row top and column left, both 1 unless changed |
screen_put(s, x, y, glyph, style), screen_text(s, x, y, text, style) |
a character, or text a character a cell, at column x and row y from 0; a wide character takes two cells |
screen_fill(s, x, y, width, height, glyph, style), screen_clear(s) |
fills a rectangle, or empties every cell |
screen_pixel(s, x, y, color) |
colors a pixel of a grid twice as tall as the screen, two square pixels a cell, drawn with half blocks |
screen_cell(s, x, y), screen_style(s, x, y) |
what a cell holds |
screen_flush(s), screen_redraw(s) |
writes the cells that changed since the last flush and gives how many; screen_redraw makes the next one write them all |
run_frames(fps, on_event, on_frame) |
calls on_frame fps times a second with the seconds since the last frame and gives on_event each event between; either returning false ends it; frames missed while the program was busy are skipped |
style_code(style) |
the terminal code that starts a style, as paint uses it |
bell() |
rings the terminal's bell |
A TermEvent has a kind: "key", "mouse", "resize", "focus",
"paste", "none", or "end". A key event has an action, "press",
"repeat", or "release"; a key, the name of the key without shift, as
"a", "1", "space", "enter", "up", "f5", or "shift";
modifiers, as "ctrl+shift"; and text, what it types, as "A" with
shift. name() gives the name read_key would, as "A" or "ctrl+c",
and has("ctrl") says whether a modifier was held. A mouse event has an
action, "press", "release", "move", or "wheel"; the button in
key, "left", "middle", "right", or "none", or the wheel's way;
and x and y from 1. A resize has the new width and height, a focus
event focused, and a paste its text.
On Windows the console's input records give presses, repeats, releases,
the mouse, and resizes; pasted text comes as keys. Elsewhere the kitty
keyboard protocol gives releases where the terminal has it, found by asking
it; SGR mouse reporting gives the mouse, SIGWINCH resizes, and bracketed
paste and focus reporting the rest. Where releases are not reported,
key_down counts a key as held for a moment after each press and while it
repeats.