TTY
Terminal UI module for raw input events, styled output, and layout utilities.
Loading
local tty = require("tty")
Input Loop
Start the raw input reader, subscribe to events, and process them in a loop:
local tty = require("tty")
local io = require("io")
local function handler()
tty.start()
local events = tty.events()
while true do
local ev = events:receive()
if not ev then break end
if ev.type == "key" then
if ev.key == "q" or (ev.ctrl and ev.key == "c") then
break
end
io.print("Key: " .. ev.key)
elseif ev.type == "resize" then
io.print("Size: " .. ev.width .. "x" .. ev.height)
end
end
tty.stop()
end
Input Control
tty.start()
Enable raw terminal input mode. The terminal switches to raw mode and begins emitting events.
local ok, err = tty.start()
Returns: boolean, error
tty.stop()
Disable raw input and restore the terminal to normal mode.
local ok, err = tty.stop()
Returns: boolean, error
tty.events()
Subscribe to terminal events and return a channel. Events are delivered as tables with a type field.
local events = tty.events()
Returns: EventChannel
tty.screen_size()
Query current terminal dimensions.
local width, height, err = tty.screen_size()
Returns: number, number, error
tty.mouse(enable)
Enable or disable mouse event tracking.
local ok, err = tty.mouse(true)
| Parameter | Type | Description |
|---|---|---|
enable |
boolean | true to enable, false to disable |
Returns: boolean, error
Event Types
Events are tables with a type field that determines which other fields are present.
Key Event
{
type = "key",
key = "a", -- printable character or key name
key_type = "runes", -- "runes" for printable, or special key name
action = "press", -- "press" or "release"
alt = false,
ctrl = false,
shift = false
}
Mouse Event
Requires tty.mouse(true).
{
type = "mouse",
action = "press", -- "press", "release", "motion", "wheel"
button = "left", -- button name
x = 10,
y = 5,
alt = false,
ctrl = false,
shift = false
}
Resize Event
{type = "resize", width = 120, height = 40}
Start Event
Emitted once after tty.start() with initial dimensions.
{type = "start", width = 120, height = 40}
Focus Event
{type = "focus", focused = true}
Paste Event
{type = "paste", text = "pasted content"}
Key Bindings
Create reusable key bindings that match against key events:
local quit = tty.bind({
keys = {"q", "ctrl+c"},
help = {key = "q/ctrl+c", desc = "quit"}
})
-- In event loop
if quit:matches(ev) then
break
end
tty.bind(config)
| Field | Type | Description |
|---|---|---|
keys |
string[] | Key patterns to match (e.g. "a", "ctrl+c", "enter") |
help |
table | Optional. {key = "...", desc = "..."} for help text |
Returns: KeyBinding
KeyBinding Methods
| Method | Returns | Description |
|---|---|---|
matches(event) |
boolean | Test if a key event matches this binding |
set_enabled(bool) |
self | Enable or disable the binding |
is_enabled() |
boolean | Check if the binding is enabled |
help() |
table | Returns {key, desc} help info |
Styles
Create styled text output using lipgloss-based styling. All style methods return a new style (immutable).
local tty = require("tty")
local io = require("io")
local title = tty.style()
:bold()
:foreground("#FF0000")
:padding(0, 1)
local box = tty.style()
:border(tty.borders.ROUNDED)
:border_foreground("#00FF00")
:width(40)
:padding(1, 2)
io.print(box:render(title:render("Hello"), "World"))
tty.style()
Create a new empty style.
Returns: Style
Style Methods
All methods return a new Style and can be chained.
Text Decoration
| Method | Parameter | Description |
|---|---|---|
foreground(color) |
string | Text color (hex "#FF0000", ANSI "9", or name) |
background(color) |
string | Background color |
bold(enable?) |
boolean | Bold text (default: true) |
italic(enable?) |
boolean | Italic text |
underline(enable?) |
boolean | Underline text |
strikethrough(enable?) |
boolean | Strikethrough text |
faint(enable?) |
boolean | Dimmed text |
blink(enable?) |
boolean | Blinking text |
reverse(enable?) |
boolean | Swap foreground/background |
Layout
| Method | Parameter | Description |
|---|---|---|
width(n) |
number | Fixed width |
height(n) |
number | Fixed height |
max_width(n) |
number | Maximum width |
max_height(n) |
number | Maximum height |
padding(...) |
numbers | Padding (CSS-style: top, right, bottom, left) |
margin(...) |
numbers | Margin (CSS-style) |
align(pos) |
number | Horizontal alignment |
align_vertical(pos) |
number | Vertical alignment |
inline(enable?) |
boolean | Inline rendering mode |
Borders
| Method | Parameter | Description |
|---|---|---|
border(name, ...) |
string, booleans | Border style, optional per-side toggles |
border_foreground(...) |
strings | Border color(s) |
border_background(...) |
strings | Border background color(s) |
Other
| Method | Description |
|---|---|
render(...) |
Render strings with this style applied |
copy() |
Create a copy of this style |
Border Constants
tty.borders.NORMAL
tty.borders.ROUNDED
tty.borders.THICK
tty.borders.DOUBLE
tty.borders.HIDDEN
Alignment Constants
tty.align.LEFT -- 0
tty.align.CENTER -- 0.5
tty.align.RIGHT -- 1
Text Utilities
Layout and measurement functions for styled text. Available under tty.text.
Measurement
local w = tty.text.width("hello") -- printable width (ANSI-aware)
local h = tty.text.height("a\nb\nc") -- line count
local w, h = tty.text.size("hello\nworld") -- both
Joining
-- Join side by side, aligned at top
local row = tty.text.join_horizontal(tty.text.position.TOP, left, right)
-- Stack vertically, centered
local col = tty.text.join_vertical(tty.text.position.CENTER, top, bottom)
Max Dimensions
local w = tty.text.max_width({"short", "a longer string"}) -- widest
local h = tty.text.max_height({"one\ntwo", "single"}) -- tallest
Placement
Place a string within a box of given dimensions:
-- Center in a 80x24 box
local out = tty.text.place(80, 24, tty.text.position.CENTER, tty.text.position.CENTER, content)
-- Horizontal only
local out = tty.text.place_horizontal(80, tty.text.position.RIGHT, content)
-- Vertical only
local out = tty.text.place_vertical(24, tty.text.position.BOTTOM, content)
Position Constants
tty.text.position.TOP -- 0
tty.text.position.LEFT -- 0
tty.text.position.CENTER -- 0.5
tty.text.position.BOTTOM -- 1
tty.text.position.RIGHT -- 1
See Also
- Terminal I/O — stdin/stdout/stderr operations
- Terminal Host — Terminal host configuration