6 releases
Uses new Rust 2024
| 0.1.0 | Mar 22, 2026 |
|---|---|
| 0.0.5 | Jan 15, 2026 |
| 0.0.4 | Nov 11, 2020 |
| 0.0.2 | Jul 29, 2020 |
#423 in Command-line interface
170KB
3K
SLoC
ANSI terminal handling for Stakker

This is a work-in-progress. Only UNIX and the first three levels described below are supported for now.
This provides several levels of abstraction at which the application may interface to the terminal, from lowest to highest:
Output buffering, input decoding, resizes and features
This can be used for applications which prefer to generate the ANSI output sequences themselves directly, for example a pager or a simple editor. The application has maximum control and can use specific ANSI features to optimise its output (for example scroll regions).
The input handling decodes keypress sequences and forwards them to application code. Terminal resizes are detected and notified as soon as they occur. Terminal features such as 256 colour support are detected and notified to the application. Terminal raw mode and input handling can be paused and resumed to allow external tools to be called.
Full-screen page buffering and minimised updates
The application code keeps one or more full-screen pages in memory which it updates locally, and the terminal code keeps its own page which represents what is currently displayed on the terminal. When the application code wishes to update the terminal, the terminal code compares the two pages and sends a minimised update.
Input handling, resizes and features are handled the same as above.
Tile-based distributed updates
On resize or relayout, the application splits the display into
non-overlapping tiles, and may pass different tiles to different
actors. Those actors are then free to draw on those tiles
whenever they like without any central coordination. Updates from
the tiles to the terminal are done automatically in the background
via a lazy! handler, batched up and optimised using the
page-update mechanism. On the next relayout, old tiles become
non-functioning, and the app top-level code must send out new
tiles to the actors that require them.
Fields and widgets (NYI)
Possibly this could be layered on top of tiles.
How to use
-
In your app's main actor's
initmethod, create aTerminalactor, and provide it with callbacks to handle input and to accept aTermShareinto your application once output has been set up. -
On receiving a
TermSharestore it somewhere and do output via thatTermSharewhenever necessary according to your application's logic, for example in response to receiving input keys or other events.
There are various levels of output from the most low-level to the highest level:
-
For simple direct ANSI output, use
TermShare::outputto get access to theOutputinstance and use it to build up your output byte by byte or with predefined ANSI calls, and then flush it to the terminal usingOutput::flush. -
For direct page-based output (like
curses), useTermShare::pageto create one or morePageinstances, and then useRegioninstances derived from the page (usingPage::fullorPage::region) to draw onto the page. Then finally write thePageyou want to display to the terminal usingTermShare::update, which will send only the minimum changes required to update the terminal. -
To split the display up into various tiles which can be then passed to other actors and updated independently of each other, use
TermShare::tileto create a new top-level tile each time you need to resize or relayout. Then break that tile up according to the layout of your application, and pass the resulting tiles to where they are needed. To draw, get aRegioninstance from the tile usingTile::fullorTile::region. This allows writing to thePagewhich backs the tiles, and automatically schedules an update via Stakker'slazy!queue which groups updates from various tiles which are made at the same time.
Examples
There are several examples available. See cargo run --example
in a checkout to get a list.
ANSI terminal handling for Stakker
This is a work-in-progress. Only UNIX is supported at the moment: output buffering, input key decoding and window resize detection, minimized updates (like curses) and tile-based layouts.
Documentation
See the crate documentation.
License
This project is licensed under either the Apache License version 2 or the MIT license, at your option. (See LICENSE-APACHE and LICENSE-MIT).
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Dependencies
~1.2–3.5MB
~56K SLoC