Tui
Model/View/Update for the command line.
Use this module to define a command-line program that uses the elm architecture.
See defineProgram
for details, or one of the examples.
Defining your program
Define your Tui program.
Very similar to a normal Node.defineProgram
, except for two special functions:
view
: Takes your Model and returns a UI
element.
gren-tui will print this to the screen, keeping track of how many lines are
output so it can clear only those lines and print again when the output
changes. This lets you do things like render progress bars, move characters
around the screen, offer menu selections, etc.
onInput
: Whenever a key is pressed, a message is sent to your app with an
Input
value. This lets you capture text, trigger events on certain
key presses, etc.
Type alias for Tui programs.
Holds information about the environment your program is running in.
This will be passed to your init function. For example:
init env =
Node.startProgram
{ model =
{ maxWidth = env.columns
, maxHeight = env.rows
}
, command =
Cmd.none
}
User Input
Value sent to your onInput
message when the program receives input
(a key is pressed, a signal is received, etc.)
Your program will receive keyboard input as the keys are pressed, as
opposed to getting a bunch of characters after Enter is pressed (under the hood
your terminal program is running in "raw mode"). For example, if someone types
"hi" after starting your program, it will receive a message with KeyChar "h"
and then another message with KeyChar "i"
.
CursorReport
is a special input type you will receive if you include
Ansi.getCursorReport
in your output. Use this to get the current row and column position of the cursor in the terminal
(where the upper-left corner of the window is row 1 column 1).
CtrlC
is the "abort" signal and gets intercepted by gren-tui to exit your
program. For now you can't depend on receiving this in your app.
Helpers
Task that exits the program.
The Stream argument should be the stdout value you get from Environment
.
This is needed to clean things up (e.g. restore cursor, unset styles, etc).
The program will exit with a 0 status code.
If you want something other than zero, use exitWithCode
.
Here's an example of using it in your update function to exit when the user presses the escape key:
case input of
Tui.Escape ->
{ model = model
, command =
Tui.exit model.stdout
|> Task.execute
}
Task that exits the program with a specific exit code.
The Stream argument should be the stdout value you get from Environment
.
This is needed to clean things up (e.g. restore cursor, unset styles, etc).
Here's an example of using it in your update function to exit if there was a failure:
case result of
Error e ->
{ model = model
, command =
Stream.sendString model.stderr "Failed!"
|> Task.andThen (\_ -> Tui.exitWithCode model.stdout 1)
|> Task.execute
}
Task to hide the cursor.
Here's an example of using it in init to hide the cursor as soon as the program starts:
init env =
Node.startProgram
{ model = {}
, command =
Tui.hideCursor env.stdout
|> Task.execute
}