Pular para o conteúdo

TTY

Módulo de UI de terminal para eventos de entrada raw, saída estilizada e utilitários de layout.

Este módulo só funciona dentro de um contexto de terminal. Você não pode usá-lo a partir de funções regulares — apenas a partir de processos executando em um Terminal Host.
local tty = require("tty")

Inicia o leitor de entrada raw, inscreve-se nos eventos e os processa em 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

Habilita o modo de entrada raw do terminal. O terminal alterna para o modo raw e começa a emitir eventos.

local ok, err = tty.start()

Retorna: boolean, error

Desabilita a entrada raw e restaura o terminal ao modo normal.

local ok, err = tty.stop()

Retorna: boolean, error

Inscreve-se nos eventos do terminal e retorna um channel. Eventos são entregues como tabelas com um campo type.

local events = tty.events()

Retorna: EventChannel, error

Consulta as dimensões atuais do terminal.

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

Retorna: number, number, error

Habilita ou desabilita o rastreamento de eventos de mouse.

local ok, err = tty.mouse(true)
ParâmetroTipoDescrição
enablebooleantrue para habilitar, false para desabilitar

Retorna: boolean, error

Eventos são tabelas com um campo type que determina quais outros campos estão presentes.

{
type = "key",
key = "a", -- caractere imprimível ou nome da tecla
key_type = "runes", -- "runes" para imprimível, ou nome de tecla especial
action = "press", -- "press" ou "release"
alt = false,
ctrl = false,
shift = false
}

Requer tty.mouse(true).

{
type = "mouse",
action = "press", -- "press", "release", "motion", "wheel"
button = "left", -- nome do botão
x = 10,
y = 5,
alt = false,
ctrl = false,
shift = false
}
{type = "resize", width = 120, height = 40}

Emitido uma vez após tty.start() com as dimensões iniciais.

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

Crie vinculações de teclas reutilizáveis que correspondem a eventos de tecla:

local quit = tty.bind({
keys = {"q", "ctrl+c"},
help = {key = "q/ctrl+c", desc = "quit"}
})
-- No loop de eventos
if quit:matches(ev) then
break
end
CampoTipoDescrição
keysstring[]Padrões de tecla a corresponder (ex: "a", "ctrl+c", "enter")
helptableOpcional. {key = "...", desc = "..."} para texto de ajuda

Retorna: KeyBinding

MétodoRetornaDescrição
matches(event)booleanTesta se um evento de tecla corresponde a esta vinculação
set_enabled(bool)selfHabilita ou desabilita a vinculação
is_enabled()booleanVerifica se a vinculação está habilitada
help()tableRetorna informações de ajuda {key, desc}

Crie saída de texto estilizada usando estilização baseada em lipgloss. Todos os métodos de estilo retornam um novo estilo (imutável).

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

Cria um novo estilo vazio.

Retorna: Style

Todos os métodos retornam um novo Style e podem ser encadeados.

MétodoParâmetroDescrição
foreground(color)stringCor do texto (hex "#FF0000", ANSI "9", ou nome)
background(color)stringCor de fundo
bold(enable?)booleanTexto em negrito (padrão: true)
italic(enable?)booleanTexto em itálico
underline(enable?)booleanTexto sublinhado
strikethrough(enable?)booleanTexto tachado
faint(enable?)booleanTexto esmaecido
blink(enable?)booleanTexto piscante
reverse(enable?)booleanInverte primeiro plano/fundo
MétodoParâmetroDescrição
width(n)numberLargura fixa
height(n)numberAltura fixa
max_width(n)numberLargura máxima
max_height(n)numberAltura máxima
padding(...)numbersPadding (estilo CSS: top, right, bottom, left)
margin(...)numbersMargin (estilo CSS)
align(pos)numberAlinhamento horizontal
align_vertical(pos)numberAlinhamento vertical
inline(enable?)booleanModo de renderização inline
MétodoParâmetroDescrição
border(name, ...)string, booleansEstilo de borda, alternâncias opcionais por lado
border_foreground(...)stringsCor(es) de borda
border_background(...)stringsCor(es) de fundo da borda
MétodoDescrição
render(...)Renderiza strings com este estilo aplicado
copy()Cria uma cópia deste estilo
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

Funções de layout e medição para texto estilizado. Disponíveis sob tty.text.

local w = tty.text.width("hello") -- largura imprimível (ciente de ANSI)
local h = tty.text.height("a\nb\nc") -- contagem de linhas
local w, h = tty.text.size("hello\nworld") -- ambos
-- Junta lado a lado, alinhado no topo
local row = tty.text.join_horizontal(tty.text.position.TOP, left, right)
-- Empilha verticalmente, centralizado
local col = tty.text.join_vertical(tty.text.position.CENTER, top, bottom)
local w = tty.text.max_width({"short", "a longer string"}) -- mais largo
local h = tty.text.max_height({"one\ntwo", "single"}) -- mais alto

Posiciona uma string dentro de uma caixa de dimensões dadas:

-- Centraliza em uma caixa 80x24
local out = tty.text.place(80, 24, tty.text.position.CENTER, tty.text.position.CENTER, content)
-- Apenas horizontal
local out = tty.text.place_horizontal(80, tty.text.position.RIGHT, content)
-- Apenas vertical
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