TUI Overview


Overview

A TUI is a text user interface. Not to be confused with a CLI, a TUI implies something more like a "console application". The TUI capabilities of compose.mk are best thought of as an interface-builder rather than a specific interface.

Support for the TUI requires no dependencies except for make and docker. It aims for low-config and sane defaults, so for high level usage it requires no configuration at all. Under the hood, the TUI uses a dockerized version of tmux for core drawing and geometry.

There's a few ways to describe what the TUI actually does.

  • Map make targets onto tmux panes.
  • Map containers (inlined, or from external compose files) onto make targets
  • Map containers on to panes.

And if you're already using compose.mk to build custom automation APIs, you can map those onto tmux panes too.


For the impatient, here's a small gallery that show-cases the type of stuff you can do with the TUI capabilities that compose.mk offers.

( You can click any of the demos to make it bigger. )

Batteries Included


Besides a dockerized tmux, the basic pre-configured components of the TUI are things like tmuxp for dynamic session management, and overridable defaults for tmux themes, tmux plugins, keybindings, etc.

These components are configurable, but not something that you necessarily have to think about. Some notable effects of the "sane defaults" policy include:

  • Click to open a new pane, or click to exit
  • Leave the TUI by hitting the escape key (if the embedded apps don't intercept the key)
  • Advanced layouts like spiral & fibbonacci, using dwindle
  • Status bar including details like user, pid, & working-dir

These elements, plus access to other tools like gum and chafa, are all setup in the embedded compose.mk:tux container, which is built and used only on demand.

Default Keybindings


Limitations

Keybindings are easy to change, but there's no way guarantee that such defaults won't collide with whatever existing applications you're trying to stitch together. See the previous section for more details.

The TUI ships with some default keybindings that are aimed at keeping things pretty user-friendly even for those who are not already familiar with tmux.

Shortcut Purpose
Escape Exit TUI
Ctrl b | Split pane vertically
Ctrl b - Split pane horizontally
Alt t Shuffle pane layout
Alt ^ Grow pane up
Alt v Grow pane down
Alt < Grow pane left
Alt > Grow pane right
Alt <left> Grow pane left
Alt <right> Grow pane right
Alt <up> Grow pane up
Alt <down> Grow pane down
Alt-1 Select pane 1
Alt-2 Select pane 2
... ...

Layout Basics


We'll start by showing how to map targets onto a specific pane orientation, using the tux.open target-family. For mapped targets, we'll use flux.ok, which has no arguments and simply succeeds without doing anything.

# Specify a horizontal layout and pass in 3 targets
$ ./compose.mk tux.open.horizontal/flux.ok,flux.ok,flux.ok

Running this command shows some log messages detailing the startup process and the first time it runs you'll see the TUI bootstrapping itself (i.e. building the necessary support containers for running tmux). (Afterwards it will be cached, so startup is much faster.)

After it starts, you'll see an interface like this, and it ran the flux.ok target for you, once in each pane.

# Other equivalent forms
$ layout=horizontal ./compose.mk tux.open/flux.ok,flux.ok,flux.ok
$ layout=h ./compose.mk tux.open/flux.ok,flux.ok,flux.ok

Vertical Orientation


For controlling the default orientation, tux.open.vertical of course works in a similar manner as you can see below.

# Specifies a vertical layout, and pass in 2 targets
$ ./compose.mk tux.open.vertical/flux.ok,flux.ok

# Other equivalent forms 
$ layout=vertical ./compose.mk tux.open/flux.ok,flux.ok
$ layout=v ./compose.mk tux.open/flux.ok,flux.ok

Spiral Orientation


The main alternative to "horizontal" and "vertical" is called "spiral", and it looks like this:

Next Steps


These 3 layouts are enough for most use-cases, but compose.mk actually supports whatever tmux does and also whatever dwindle supports.

Of course, flux.ok is not very interesting, but it is the simplest target. We'll move into more practical examples in the following sections, and almost everything else we'll look at is some variation of the principles above.