Gren TUI
Write purely functional, type-safe terminal apps using The Elm Architecture. Easily create complex, responsive UIs with an interface inspired by elm-ui. All in the very pleasant Gren programming language.
Example
A full program showing a running clock with a border in the terminal:
module Main exposing (main)
import Init
import Node
import Stream exposing (Stream)
import Task
import Time
import Tui
import UI
import UI.Border
main : Tui.Program Model Msg
main =
Tui.defineProgram
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
, onInput = GotInput
}
-- MODEL
type alias Model =
{ time : Time.Posix
, stdout : Stream
}
init : Tui.Environment -> Init.Task { model : Model, command : Cmd Msg }
init env =
Node.startProgram
{ model =
{ time = Time.millisToPosix 0
, stdout = env.stdout
}
, command =
Tui.hideCursor env.stdout
|> Task.execute
}
-- VIEW
view : Model -> UI.Element
view model =
let
hour = String.fromInt (Time.toHour Time.utc model.time)
minute = String.fromInt (Time.toMinute Time.utc model.time)
second = String.fromInt (Time.toSecond Time.utc model.time)
in
UI.bordered [] UI.Border.rounded <|
UI.text [] (hour ++ ":" ++ minute ++ ":" ++ second)
-- UPDATE
type Msg
= Tick Time.Posix
| GotInput Tui.Input
update : Msg -> Model -> { model : Model, command : Cmd Msg }
update msg model =
case msg of
Tick time ->
{ model = { model | time = time }
, command = Cmd.none
}
GotInput input ->
case input of
Tui.Escape ->
{ model = model
, command =
Tui.exit model.stdout
|> Task.execute
}
_ ->
{ model = model
, command = Cmd.none
}
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every 1000 Tick
Usage
If you haven't already, install node, install gren, and take a look at the book if you want to get up to speed with the language.
Then create a gren node application:
mkdir myapp
cd myapp
gren init --platform=node
Install the gren-tui
package:
gren package install blaix/gren-tui
Then create a src/Main.gren
file. For a starting point, see:
Then compile and run with:
gren make src/Main.gren
node app
Getting Help or Updates
If you have questions, suggestions, find a bug, or want to follow updates to the package, you can:
- Follow me on mastodon at @blaix@hachyderm.io.
- Join the
#gren-tui
channel on the gren discord. - File an issue on github.