-- Showcase of the tui module's output features: styled markup, message
-- blocks, outline blocks, and the raw/screenInfo building blocks.
-- Non-interactive — safe to run piped (colors degrade to plain text).
--
-- Run with: cargo run -- lua/tui_styles.lua
local function banner(s)
print("\n=== " .. s .. " ===")
end
----------------------------------------------------------------------
banner("1. tui.styled — built-in tags")
----------------------------------------------------------------------
print(tui.styled("info is bold green and error is white on red "))
-- HTML-like shortcuts.
print(tui.styled("bold italic underscore strikethrough"))
----------------------------------------------------------------------
banner("2. Inline styles: fg / bg / options")
----------------------------------------------------------------------
print(tui.styled("named colors>, bright variants>, gray>"))
print(tui.styled("hex truecolor #c0392b> and short #0af>"))
print(tui.styled("background> bold> both>"))
print(tui.styled(" all combined in one tag >"))
-- Shorthand: bare colors are the foreground, on- the background,
-- option names apply directly; mixes with built-in names and key=value.
print(tui.styled("alarm> <#f0a;u>pink underline> bold green>"))
----------------------------------------------------------------------
banner("3. Custom presets — tui.addPreset")
----------------------------------------------------------------------
tui.addPreset("keyword", "fg=white;bg=magenta")
tui.addPreset("em", "i;bold") -- specs can use shorthand and reference other presets
print(tui.styled("the local keyword is important"))
tui.block("presets work as block styles too", { style = "keyword" })
----------------------------------------------------------------------
banner("4. Nesting, links, escaping")
----------------------------------------------------------------------
-- Inner tags override only what they set; the rest is inherited.
print(tui.styled("outer bold inherits the red bg> and back"))
-- > closes the innermost style; fg=default resets to the terminal color.
print(tui.styled("red terminal default> red again>"))
-- OSC-8 hyperlink (clickable in supporting terminals, plain text elsewhere).
print(tui.styled("read the docs> for details"))
-- \< escapes a bracket; unknown tags pass through literally, never error.
print(tui.styled("literal \\ stays, too, a < b as well"))
----------------------------------------------------------------------
banner("5. Message blocks (Symfony style)")
----------------------------------------------------------------------
tui.success("Deployment finished without errors")
tui.warning({ "Disk usage above 80%", "Consider pruning old artifacts" })
tui.error("Build failed")
tui.caution("This will overwrite production data")
tui.info("14 files processed")
tui.note("Long messages word-wrap to the terminal width and continuation lines stay aligned under the label lorem ipsum dolor sit amet")
tui.comment("git push --force-with-lease")
-- The generic form: everything is configurable.
tui.block(
"Custom label, style and prefix",
{ label = "HEY", style = "fg=black;bg=cyan", prefix = " > ", padding = true }
)
----------------------------------------------------------------------
banner("6. Outline blocks (colored borders, plain content)")
----------------------------------------------------------------------
tui.outlineSuccess("All tests passed")
tui.outlineWarning("3 deprecation warnings", { title = "Heads up" }) -- opts.title overrides the preset
tui.outlineBlock({ "Generic box.", "Multiple messages are separated by a blank line." }, {
title = "Stats",
style = "fg=magenta",
})
----------------------------------------------------------------------
banner("7. tui.raw + tui.screenInfo — progress bar building blocks")
----------------------------------------------------------------------
local info = tui.screenInfo()
print("screen:", (info.width or "?") .. "x" .. (info.height or "?"), "tty:", info.tty, "colors:", info.colors)
-- A minimal in-place progress bar: \r rewinds the line, tui.raw prints
-- without a newline and flushes. Width adapts to the terminal; without a
-- tty the \r redraw trick is pointless, so print the final state once.
local width = math.clamp((info.width or 80) - 20, 10, 40)
local start = info.tty and 0 or width
for i = start, width do
local bar = string.rep("#", i) .. string.rep(".", width - i)
tui.raw("\r[", bar, "] ", math.floor(i / width * 100 + 0.5), "%")
os.sleep(0.02)
end
tui.raw("\n")