beamtea behaviour (beamtea v0.1.2)
View Sourcebeamtea — a delightful terminal UI framework for the BEAM, built on prim_tty and inspired by Bubble Tea and The Elm Architecture.
A program is three pure functions:
init(Flags) -> {Model, Cmd}— the starting model and an initial commandupdate(Msg, Model) -> {Model, Cmd}— fold a message into the modelview(Model) -> iodata()— render the model to the full screen
Supply them either as a module implementing the beamtea behaviour or as a map #{init => F, update => F, view => F}, then call start/1.
Messages your update/2 will receive from the runtime:
{key, Key}— a keypress (seebeamtea_key){resize, {Cols, Rows}}— the terminal was resized
plus any message produced by the commands you return.
Summary
Functions
Run several commands.
Deliver Msg repeatedly, every Ms milliseconds, until the program quits. (0.1.0 timers cannot be individually cancelled.)
Deliver Msg back to update/2 as soon as possible.
A command that does nothing.
Normalize a program (module or map) into the internal record form.
Ask the runtime to quit after this update.
Run several commands (ordering is not otherwise significant in 0.1.0).
Equivalent to start(Program, undefined, #{}).
Equivalent to start(Program, Flags, #{}).
Start a program and block until it quits.
Run Fun asynchronously; its return value is delivered to update/2.
Deliver Msg once, after Ms milliseconds.
The current terminal size {Cols, Rows}. Callable from init/1 and view/1 (they run in the runtime process), so a view can size its content to the terminal without threading the size through the model. The size also arrives in update/2 as {resize, {Cols, Rows}} if you prefer to store it. Returns {80, 24} if called outside a running program.
Types
-type cmd() :: none | ok | quit | {msg, msg()} | {tick, non_neg_integer(), msg()} | {every, pos_integer(), msg()} | {task, fun(() -> msg())} | fun(() -> msg()) | {batch, [cmd()]} | {seq, [cmd()]} | [cmd()].
-type model() :: term().
-type msg() :: {key, beamtea_key:key()} | {resize, {pos_integer(), pos_integer()}} | term().
Callbacks
Functions
Run several commands.
-spec every(pos_integer(), msg()) -> cmd().
Deliver Msg repeatedly, every Ms milliseconds, until the program quits. (0.1.0 timers cannot be individually cancelled.)
Deliver Msg back to update/2 as soon as possible.
-spec none() -> cmd().
A command that does nothing.
-spec normalize(program()) -> #beamtea_prog{init :: fun((term()) -> {term(), term()}), update :: fun((term(), term()) -> {term(), term()}), view :: fun((term()) -> iodata())}.
Normalize a program (module or map) into the internal record form.
-spec quit() -> cmd().
Ask the runtime to quit after this update.
Run several commands (ordering is not otherwise significant in 0.1.0).
Equivalent to start(Program, undefined, #{}).
Equivalent to start(Program, Flags, #{}).
Start a program and block until it quits.
Returns {ok, FinalModel} on a clean exit, or {error, Reason} if the program could not start (e.g. not_a_terminal when stdout is not a tty) or crashed.
Run beamtea programs so they own the terminal — use bin/beamtea-run or start the VM with stty -isig and erl +Bi -noshell -noinput. Launching from an interactive rebar3 shell will conflict with the shell's own tty handling and route Ctrl-C to the BEAM break handler. See the README.
Opts understands:
alt_screen => boolean()(defaulttrue) — use the alternate screen buffercatch_ctrl_c => boolean()(defaulttrue) — quit on Ctrl-C instead of passing it toupdate/2layout => top_left | center | {place, Opts}(defaulttop_left) — position the whole view within the terminal, so a small view can fill/centre the screen. Seebeamtea_layout.centerand{place, ...}re-flow automatically on resize.
Run Fun asynchronously; its return value is delivered to update/2.
-spec tick(non_neg_integer(), msg()) -> cmd().
Deliver Msg once, after Ms milliseconds.
-spec window_size() -> {pos_integer(), pos_integer()}.
The current terminal size {Cols, Rows}. Callable from init/1 and view/1 (they run in the runtime process), so a view can size its content to the terminal without threading the size through the model. The size also arrives in update/2 as {resize, {Cols, Rows}} if you prefer to store it. Returns {80, 24} if called outside a running program.