Skip to content

State & Lines

Two small contracts the rest of the API leans on: rune.state exposes live client state to renderers like bars and layout code, and line objects are what hook and trigger handlers receive for server output.

rune.state.connected -- bool, connection status
rune.state.address -- server address, scheme included
rune.state.scroll_mode -- "live" or "scrolled"
rune.state.scroll_lines -- new lines arrived while scrolled
rune.state.width -- terminal width
rune.state.height -- terminal height
rune.line.new(text) -- build a line object from plain text
line:raw() -- the line with ANSI codes intact
line:clean() -- the line with ANSI codes stripped

A read-only proxy over live, client-owned state — reads always reflect the current values, and writing any field raises an error.

Field Type Description
connected bool Whether a connection is up
address string The connected address, scheme included (e.g. tls://mud.example.com:4000)
scroll_mode string "live", or "scrolled" while scrolled back
scroll_lines number New lines received while scrolled
width number Terminal width in columns
height number Terminal height in rows

Because it’s always current, rune.state is the natural input for bar renderers:

rune.ui.bar("status", function(width)
local s = rune.state
local left = s.connected
and rune.style.green("") .. " " .. s.address
or rune.style.gray("● Disconnected")
return { left = left }
end)

Server output arrives in handlers as line objects, not plain strings: "output" and "prompt" hook handlers receive one, and trigger function actions get one as ctx.line. Two methods:

line:raw() -- ANSI codes included; use when re-emitting styled text
line:clean() -- ANSI stripped; use when matching or parsing

:clean() is computed lazily and cached, so calling it repeatedly is cheap.

rune.line.new(text) -> line
  • text (string) — the raw text, ANSI codes and all.

Builds a line object compatible with what handlers receive. You rarely need this — the main use is constructing a rewritten line to pass along, or feeding synthetic lines through code that expects the line contract:

local l = rune.line.new("\027[31malert\027[0m")
rune.echo(l:clean()) -- "alert"

Related: Hooks guide · rune.trigger · rune.ui · Core