Nottui is a toolkit for making terminal user-interfaces. It builds upon Notty, adding a layout DSL and support for event dispatch, and Lwd which is used for interactivity.
This repo is forked from Lwd I'd like to get it reintegrated with that at some point, I'm just waiting until let-def has a little more time on his plate
The package is distributed through opam:
$ opam install nottui
There is a tutorial for nottui which will take you through the basics of making a small application, it covers:
- how to do layout
- reactive values
- handling keyboard input
- and much more!
See tutorial
For more details on how to write Nottui applications and how Nottui works see the docs. I recommend reading at least the fundimentals.
Here are a few examples of using Nottui, more can be found in the examples folder:
Let's start with Hello world.
#require "nottui";;
open Nottui;;
Ui_loop.run (Lwd.pure (W.printf "Hello world"));;
Running the application is just a matter of calling Ui_loop.run
with a ui
value.
Note: Press Ctrl-Q to return to the top-level (or shell).
Now we will count the number of clicks on a button.
let vcount = Lwd.var 0;;
let button count =
W.button (Printf.sprintf "Clicked %d times!" count)
(fun () -> Lwd.set vcount (count + 1));;
Ui_loop.run (Lwd.map button (Lwd.get vcount));;
We reserve state for holding the number of clicks, we render a button and increment the state when clicked.
type tree = Tree of string * (unit -> tree list)
let rec tree_ui (Tree (label, child)) =
let opened = Lwd.var false in
let render is_opened =
let btn_text = if is_opened then "[-] " else "[+] " in
let btn_action () = Lwd.set opened (not is_opened) in
let btn = W.button (btn_text ^ label) btn_action in
let layout node forest =
Ui.join_y node (Ui.join_x (Ui.space 2 0) forest)
in
if is_opened
then Lwd.map (layout btn) (forest_ui (child ()))
else Lwd.pure btn
in
Lwd.join (Lwd.map render (Lwd.get opened))
and forest_ui nodes =
Lwd_utils.pack Ui.pack_y
(List.map tree_ui nodes)
;;
let rec fake_fs () = [
Tree ("bin", fake_fs);
Tree ("home", fake_fs);
Tree ("usr", fake_fs);
] in
Ui_loop.run (forest_ui (fake_fs ()));;