Skip to content

Layout & UI

Rune’s screen is one main output viewport with docks above and below. Docks hold bars (single-line, script-rendered), panes (multi-line output buffers), and the built-in components input, status, and separator. You declare the arrangement once:

rune.ui.layout({
top = { { name = "chat", height = 10 } }, -- a pane, 10 lines tall
bottom = { "input", "separator", "status" }, -- input, a rule, the status bar
})

Reading that: a chat pane docked on top; at the bottom, the input line, a separator rule, and the status bar below it.

┌─────────────────────────────┐
│ chat pane (10 lines) │ top dock
├─────────────────────────────┤
│ │
│ main output viewport │
│ │
├─────────────────────────────┤
│ > input line │ bottom dock
│ ─────────────────────────── │
│ status bar │
└─────────────────────────────┘
  • Entries are component names: a bar name, a pane name, or the built-ins "input", "status", "separator". A table entry ({ name = ..., height = n }) sets an explicit height in lines (a pane spends two of those on its header and bottom border).
  • rune.ui.layout replaces the whole layout. Always include the bottom dock with "input", because nothing re-adds the input line if you leave it out.
  • Unknown names are skipped; hidden panes and empty bars take no space.
  • A bar or pane renders only if a dock names it. Registering a renderer or writing to a pane is not enough — the layout decides what appears.
  • The default layout is bottom = { "input", "status" }. You only need rune.ui.layout to change it.
  • Bars: you write a render function, and rune calls it with the current width every 250ms. The built-in status bar is one of these.
  • Panes: named buffers that show their most recent lines. Write to them from triggers; toggle them from binds.
  • Pickers: fuzzy overlays for commands, worlds, and anything your scripts want to offer.

The quake console recipe combines all of this in one short script.

Bars usually render from rune.state, a read-only table the client keeps current: connected, address, scroll_mode, scroll_lines, width, height. When your own state changes and a bar should reflect it now, call rune.ui.refresh_bars().

Related: rune.ui reference, Bars, Panes, Pickers