Zum Inhalt springen

TTY

Terminal-UI-Modul für Roh-Eingabeereignisse, formatierte Ausgabe und Layout-Hilfsfunktionen.

Dieses Modul funktioniert nur im Terminal-Kontext. Du kannst es nicht aus regulären Funktionen verwenden — nur aus Prozessen, die auf einem Terminal-Host laufen.
local tty = require("tty")

Starte den Roh-Eingabe-Reader, abonniere Ereignisse und verarbeite sie in einer Schleife:

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

Aktiviert den Roh-Eingabemodus des Terminals. Das Terminal wechselt in den Raw-Modus und beginnt, Ereignisse auszugeben.

local ok, err = tty.start()

Rückgabe: boolean, error

Deaktiviert die Roh-Eingabe und stellt das Terminal in den Normalmodus zurück.

local ok, err = tty.stop()

Rückgabe: boolean, error

Abonniert Terminal-Ereignisse und gibt einen Channel zurück. Ereignisse werden als Tabellen mit einem type-Feld geliefert.

local events = tty.events()

Rückgabe: EventChannel, error

Fragt die aktuellen Terminal-Dimensionen ab.

local width, height, err = tty.screen_size()

Rückgabe: number, number, error

Aktiviert oder deaktiviert das Maus-Ereignis-Tracking.

local ok, err = tty.mouse(true)
ParameterTypBeschreibung
enablebooleantrue zum Aktivieren, false zum Deaktivieren

Rückgabe: boolean, error

Ereignisse sind Tabellen mit einem type-Feld, das bestimmt, welche anderen Felder vorhanden sind.

{
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
}

Erfordert 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
}
{type = "resize", width = 120, height = 40}

Wird einmal nach tty.start() mit den initialen Dimensionen ausgegeben.

{type = "start", width = 120, height = 40}
{type = "focus", focused = true}
{type = "paste", text = "pasted content"}

Erstelle wiederverwendbare Tastenbindungen, die mit Tastenereignissen abgeglichen werden:

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
FeldTypBeschreibung
keysstring[]Zu vergleichende Tastenmuster (z. B. "a", "ctrl+c", "enter")
helptableOptional. {key = "...", desc = "..."} für Hilfetext

Rückgabe: KeyBinding

MethodeRückgabeBeschreibung
matches(event)booleanPrüft, ob ein Tastenereignis zu dieser Bindung passt
set_enabled(bool)selfAktiviert oder deaktiviert die Bindung
is_enabled()booleanPrüft, ob die Bindung aktiviert ist
help()tableGibt {key, desc}-Hilfeinformationen zurück

Erstelle formatierte Textausgabe mit lipgloss-basiertem Styling. Alle Stilmethoden geben einen neuen Stil zurück (unveränderlich).

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"))

Erstellt einen neuen leeren Stil.

Rückgabe: Style

Alle Methoden geben einen neuen Style zurück und können verkettet werden.

MethodeParameterBeschreibung
foreground(color)stringTextfarbe (Hex "#FF0000", ANSI "9" oder Name)
background(color)stringHintergrundfarbe
bold(enable?)booleanFetter Text (Standard: true)
italic(enable?)booleanKursiver Text
underline(enable?)booleanUnterstrichener Text
strikethrough(enable?)booleanDurchgestrichener Text
faint(enable?)booleanGedimmter Text
blink(enable?)booleanBlinkender Text
reverse(enable?)booleanVorder- und Hintergrund tauschen
MethodeParameterBeschreibung
width(n)numberFeste Breite
height(n)numberFeste Höhe
max_width(n)numberMaximale Breite
max_height(n)numberMaximale Höhe
padding(...)numbersPadding (CSS-Stil: oben, rechts, unten, links)
margin(...)numbersMargin (CSS-Stil)
align(pos)numberHorizontale Ausrichtung
align_vertical(pos)numberVertikale Ausrichtung
inline(enable?)booleanInline-Rendering-Modus
MethodeParameterBeschreibung
border(name, ...)string, booleansRahmenstil, optionale Pro-Seiten-Toggles
border_foreground(...)stringsRahmenfarbe(n)
border_background(...)stringsRahmen-Hintergrundfarbe(n)
MethodeBeschreibung
render(...)Rendert Strings mit angewendetem Stil
copy()Erstellt eine Kopie dieses Stils
tty.borders.NORMAL
tty.borders.ROUNDED
tty.borders.THICK
tty.borders.DOUBLE
tty.borders.HIDDEN
tty.align.LEFT -- 0
tty.align.CENTER -- 0.5
tty.align.RIGHT -- 1

Layout- und Messfunktionen für formatierten Text. Verfügbar unter tty.text.

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
-- Side-by-side verbinden, oben ausgerichtet
local row = tty.text.join_horizontal(tty.text.position.TOP, left, right)
-- Vertikal stapeln, zentriert
local col = tty.text.join_vertical(tty.text.position.CENTER, top, bottom)
local w = tty.text.max_width({"short", "a longer string"}) -- breitestes
local h = tty.text.max_height({"one\ntwo", "single"}) -- höchstes

Platziert einen String in einer Box mit gegebenen Dimensionen:

-- Zentrieren in einer 80x24-Box
local out = tty.text.place(80, 24, tty.text.position.CENTER, tty.text.position.CENTER, content)
-- Nur horizontal
local out = tty.text.place_horizontal(80, tty.text.position.RIGHT, content)
-- Nur vertikal
local out = tty.text.place_vertical(24, tty.text.position.BOTTOM, content)
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