bevy_slt 0.2.0

Bevy integration for SuperLightTUI (slt)
Documentation

bevy_slt

Bevy integration for SuperLightTUI.

Terminal apps

SltTerminalPlugin (feature terminal, on by default) renders to the real terminal. It installs an SltTerminalContext non-send resource at startup, forwards terminal input as Bevy messages (SltKeyMessage, SltMouseMessage, SltFocusMessage, SltPasteMessage, SltResizeMessage) in PreUpdate, writes AppExit on Ctrl+C (disable with .ctrl_c_exit(false)), and restores the terminal on exit or panic.

use std::time::Duration;

use bevy::app::ScheduleRunnerPlugin;
use bevy::prelude::*;
use bevy_slt::{SltTerminalContext, SltTerminalPlugin};
use slt::RunConfig;

fn main() {
    App::new()
        .add_plugins((
            MinimalPlugins.set(ScheduleRunnerPlugin::run_loop(Duration::from_secs_f32(1.0 / 30.0))),
            SltTerminalPlugin::new(RunConfig::default().mouse(true)),
        ))
        .add_systems(Update, draw)
        .run();
}

fn draw(mut context: NonSendMut<SltTerminalContext>, mut exit: MessageWriter<AppExit>) -> Result {
    let keep_going = context.draw(|ui| {
        if ui.key('q') {
            ui.quit();
        }
        ui.text("hello from slt inside bevy, q quits");
    })?;

    if !keep_going {
        exit.write(AppExit::Success);
    }
    Ok(())
}

See examples/widget_demo.rs for tabs, tables, inputs, and mouse handling.

Headless rendering

SltHeadlessPlugin renders to an in-memory buffer and publishes each frame as the SltOutput resource (plain text plus styled cells), for display with Bevy UI, a texture, or assertions in tests. Queue input with SltContext::push_event.

use bevy_app::App;
use bevy_ecs::error::Result;
use bevy_ecs::prelude::*;
use bevy_slt::{SltHeadlessContext, SltHeadlessPlugin, SltOutput};

let mut app = App::new();
app.add_plugins(SltHeadlessPlugin::default()).add_systems(
    bevy_app::Update,
    |mut context: NonSendMut<SltHeadlessContext>| -> Result {
        context.draw(|ui| {
            ui.text("hello from slt");
        })?;
        Ok(())
    },
);

app.update();
let output = app.world().resource::<SltOutput>();
assert!(output.text.contains("hello from slt"));

Headless-only consumers can depend on bevy_slt with default-features = false to skip the terminal machinery entirely.

Compatibility

bevy_slt Bevy
0.1.x 0.18
0.2.x 0.19