Tui
In order for your application to present as a terminal user interface, you need to do 2 things:
- Enter raw mode: This is required to get key or mouse inputs from a user
- Enter the alternate screen: This is required to preserve the state of the user’s current terminal contents
Define a couple of functions to init
and restore
the terminal state:
use ratatui::prelude::{CrosstermBackend, Terminal};
pub type Tui = Terminal<CrosstermBackend<std::io::Stdout>>;
pub fn init() -> color_eyre::Result<Tui> { use crossterm::terminal::EnterAlternateScreen; crossterm::terminal::enable_raw_mode()?; crossterm::execute!(std::io::stdout(), EnterAlternateScreen)?; let mut terminal = Terminal::new(CrosstermBackend::new(std::io::stdout()))?; terminal.clear()?; terminal.hide_cursor()?; Ok(terminal)}
pub fn restore() -> color_eyre::Result<()> { use crossterm::terminal::LeaveAlternateScreen; crossterm::execute!(std::io::stdout(), LeaveAlternateScreen)?; crossterm::terminal::disable_raw_mode()?; Ok(())}
init
returns the ratatui::terminal::Terminal
struct.
After calling init
, the terminal is now in the appropriate state to make your application behave
as a TUI application. Just have to make sure we call tui::restore()
at the end of your program.
Let’s update main.rs
to the following:
mod crates_io_api_helper;mod tui;
#[tokio::main]async fn main() -> color_eyre::Result<()> { let mut tui = tui::init()?;
tui.draw(|frame| { frame.render_widget( ratatui::widgets::Paragraph::new("hello world"), frame.size(), ) })?;
tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;
tui::restore()?;
Ok(())}
If you run this using cargo run
, your terminal should enter the alternate screen, display the
"hello world"
Paragraph widget, sleep for 5 seconds and reset the terminal back to the normal
state.
Your file structure should now look like this:
.├── Cargo.lock├── Cargo.toml└── src ├── crates_io_api_helper.rs ├── main.rs └── tui.rs
Next, we will handle errors.