std/terminal_emulator
A terminal, as a program that draws terminals itself keeps one, instead of using xterm.js: the bytes a program writes are read as VT and xterm terminals read them (ECMA-48 and the xterm extensions in common use) and drawn into a grid of cells; the user's keys, pastes, mouse events, and focus changes are written as the program asked for them.
import "std/terminal_emulator"
Terminal t = terminal_emulator(80, 24)
t.feed(to_bytes("\u{1b}[1;31mred\u{1b}[0m and plain"))
print(t.line(0), t.cell(0, 0).style.foreground) // red and plain 1
write_input(program, t.encode_key("up")) // ESC [ A, or ESC O A
write_input(program, to_bytes(t.take_replies())) // what the program asked| Method | |
|---|---|
t.feed(data), t.feed_text(text) |
reads and draws what the program wrote; a character or sequence cut in two waits for its end |
t.text(), t.line(row), t.cell(row, column), t.cursor() |
the screen: its text, a row's, a TerminalCell's text and style, and the cursor's row and column, from 0 |
t.history() |
the lines scrolled off the top of the main screen, oldest first, at most scrollback_limit (10,000) |
t.resize(columns, rows) |
another size; rows that no longer fit go to the scrollback, and the cursor stays on the screen |
t.take_replies() |
the answers to what the program asked, as where the cursor is (DSR), what the terminal is (DA), and its size, to write back to it |
t.encode_key(key, shift, alt, ctrl) |
what a key sends: "up", "down", "right", "left", "home", "end", "insert", "delete", "page_up", "page_down", "f1" to "f12", "enter", "tab", "backspace", "escape", or a character; arrows follow application cursor mode |
t.encode_paste(text) |
pasted text, bracketed when the program asked for it |
t.encode_mouse(action, button, row, column, shift, alt, ctrl) |
a mouse event, "press", "release", "move", "scroll_up", or "scroll_down", in the tracking mode and encoding (X10, SGR, UTF-8, urxvt) the program chose; nothing when it does not want it |
t.encode_focus(focused) |
focus in or out, when asked for |
A TerminalStyle has foreground, background, and underline_color
(-1 for the terminal's own, 0 to 255 for the palette, 0x1000000 plus red,
green, and blue for 24-bit), bold, dim, italic, underline and its
underline_kind (1 single, 2 double, 3 curly, 4 dotted, 5 dashed),
blink, inverse, hidden, strike, overline, and the link its text
is part of. A Terminal also says its title, icon_title, directory
(OSC 7), clipboard (OSC 52, in base64), bells, and the modes the
program set: cursor_visible, cursor_shape, auto_wrap, origin_mode,
insert_mode, new_line_mode, application_cursor,
application_keypad, bracketed_paste, mouse_tracking,
mouse_encoding, focus_events, and alternate.
What it reads: the C0 controls; ESC sequences for the cursor's saving and restoring, index, reverse index, next line, tab stops, keypad modes, the character sets G0 to G3 with the DEC line-drawing set, DECALN, and reset; CSI sequences for moving the cursor, erasing, inserting and deleting characters and lines, scrolling, scroll regions, tab stops, repeating, styles (SGR, with colons too), modes, reports, and the cursor's shape; control characters inside a CSI sequence, which act at once; and OSC strings for the title, the folder, links (OSC 8), and the clipboard. DCS, PM, APC, and SOS strings are read and passed over.