Program<M extends Model> class TUI

The TUI program runtime.

Program manages the complete lifecycle of a TUI application:

  1. Initializes the terminal (raw mode, alt screen, etc.)
  2. Calls Model.init and executes any returned command
  3. Renders the initial view
  4. Listens for input and dispatches messages to Model.update
  5. Re-renders after each update
  6. Executes commands returned from updates
  7. Cleans up on exit (restores terminal state)

Example

void main() async {
  final program = Program(MyModel());
  await program.run();
}

With Options

void main() async {
  final program = Program(
    MyModel(),
    options: ProgramOptions(
      altScreen: true,
      mouse: true,
      fps: 30,
    ),
  );
  await program.run();
}

Panic Recovery

By default, the program catches all exceptions, restores the terminal state, and prints a formatted error message. This ensures the terminal is never left in a broken state.

// Disable panic catching for debugging
final program = Program(
  MyModel(),
  options: ProgramOptions().withoutCatchPanics(),
);

Message Filtering

You can filter messages before they reach the model using a filter function:

final program = Program(
  MyModel(),
  options: ProgramOptions().withFilter((model, msg) {
    // Prevent quit if there are unsaved changes
    if (msg is QuitMsg && model is MyModel && model.hasUnsavedChanges) {
      return const ShowSavePromptMsg();
    }
    return msg; // Allow message through
  }),
);

The runtime that manages the TUI event loop and rendering. The TUI program runtime.

The TUI runtime follows The Elm Architecture (TEA) pattern, which separates state, logic, and presentation:

  • Model: The state of your application. It should be immutable.
  • Update: A pure function that takes a Msg and the current Model, and returns a new Model and an optional Cmd.
  • View: A pure function that takes the Model and returns a String (or a View object for advanced metadata) representing the UI.
┌─────────────────────────────────────────────────────┐
│                     Program                          │
│                                                      │
│    ┌───────┐     ┌────────┐     ┌──────┐            │
│    │ Model │────▶│ update │────▶│ view │            │
│    └───────┘     └────────┘     └──────┘            │
│        ▲              │              │               │
│        │              │              ▼               │
│        │         ┌────────┐     ┌────────┐          │
│        └─────────│  Cmd   │     │ Screen │          │
│                  └────────┘     └────────┘          │
│                       │                              │
│                       ▼                              │
│                  ┌────────┐                          │
│                  │  Msg   │◀──── User Input          │
│                  └────────┘                          │
└─────────────────────────────────────────────────────┘
  1. Initialization: The Program starts, calls Model.init(), and executes the returned Cmd.
  2. Event Loop: The program waits for input (stdin, signals, or commands).
  3. Update: When a Msg arrives, Model.update(msg) is called.
  4. Render: If the model changed, Model.view() is called and the result is rendered to the terminal.
  5. Termination: The program exits when a QuitMsg is received or Cmd.quit() is executed.

Artisanal supports multiple rendering strategies:

  • Standard: Simple ANSI output for basic terminals.
  • Ultraviolet: High-performance diff-based rendering with cell buffers.
  • ANSI Compression: Minimizes output by removing redundant SGR sequences.

Configure these via ProgramOptions.

Constructors

Program(M _initialModel, {ProgramOptions options = const ProgramOptions(), TuiTerminal? terminal})
Creates a new TUI program with the given initial model.

Properties

currentModel → M?
Returns the current model (for testing).
no setter
finalModel → M?
Final model after the program exits (captured before cleanup).
no setter
hashCode int
The hash code for this object.
no setterinherited
isRunning bool
Whether the program is currently running.
no setter
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
wasKilled bool
Returns true if the program was terminated via kill rather than quit.
no setter

Methods

forceRepaint() → void
Forces a repaint of the current view.
kill() → void
Immediately terminates the program without a final render.
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
printf(String format, List<Object?> args) → void
Prints formatted text above the TUI output.
println(String text) → void
Prints a line of text above the TUI output.
quit() → void
Requests the program to quit.
run() Future<void>
Runs the TUI program.
send(Msg msg) → void
Sends a message to the program.
toString() String
A string representation of this object.
inherited
wait() Future<void>
Returns a Future that completes when the program exits.

Operators

operator ==(Object other) bool
The equality operator.
inherited