Harlock — a pure-Elixir TUI framework for Unix terminals.
The two entry points:
Harlock.run/3— blocking. Starts the app, returns when it exits.Harlock.start_link/3— non-blocking. Returns a supervisor pid for embedding inside an existing OTP application.
An app owns the terminal it runs in, so start it with mix run, not from an
IEx prompt: IEx's own terminal driver reads the same tty, and the app does
not receive keystrokes.
smoke/0 and smoke_crash/0 are diagnostics for the terminal layer.
Summary
Functions
Start an app and block until it exits.
Round-trip smoke test. Opens /dev/tty, writes a greeting in the alt-screen, reads up to 5 bytes from the user, echoes what was typed, and restores the terminal. Should leave the terminal in a usable state after returning.
Crash-path smoke test. Spawns a linked child that opens /dev/tty and then
raises. with_raw's nested try/after blocks restore the terminal before
the process dies. Returns {cleanup, reason} where cleanup is :ok if
the restore ran.
Start an app under the caller's supervision tree without blocking.
Types
Functions
Start an app and block until it exits.
Returns:
{:ok, reason}when the app ends itself —update/2returned:quit, or the runtime reported why it stopped.{:error, reason}when the supervisor could not start, or went down without the app ending itself, e.g. after a crash inupdate/2. The terminal has been restored either way.
The caller is linked to the app supervisor, so killing the caller tears the
app down and restores the terminal. The link does not work the other way:
while run/3 waits it traps exits, so the app going down is a return value
rather than an exit signal that kills the caller. Exit trapping is put back as
it was before returning, and an abnormal exit from any other process linked
to the caller still ends it, after stopping the app, as it would have without
run/3 in between.
Options:
:theme— aHarlock.Theme.t()(or keyword list / map convertible viaHarlock.Theme.build/1). Defaults toHarlock.Theme.default/0.:mouse— turn on mouse reporting (defaultfalse). Clicks focus elements and press buttons and checkboxes, the wheel scrolls viewports and tables, and anything not routed arrives inupdate/2as{:mouse, action, button, col, row, mods}. SeeHarlock.App. Off by default because while it is on the terminal's own click-and-drag text selection needs a modifier (usually Shift, or Option on macOS).
Round-trip smoke test. Opens /dev/tty, writes a greeting in the alt-screen, reads up to 5 bytes from the user, echoes what was typed, and restores the terminal. Should leave the terminal in a usable state after returning.
Crash-path smoke test. Spawns a linked child that opens /dev/tty and then
raises. with_raw's nested try/after blocks restore the terminal before
the process dies. Returns {cleanup, reason} where cleanup is :ok if
the restore ran.
@spec start_link(app(), init_arg(), keyword()) :: Supervisor.on_start()
Start an app under the caller's supervision tree without blocking.
Returns {:ok, sup_pid}. The caller is responsible for handling the
supervisor's lifecycle (linking, monitoring, stopping), and receives
{:harlock_done, reason} when the app ends itself. Useful when embedding
Harlock inside a larger OTP app that owns its terminal. The IEx caveat in
the module documentation applies here too, so a dashboard in a project
usually started with iex -S mix needs a separate mix run entry point.
Accepts the same options as run/3.