Crate modalkit_ratatui

source ·
Expand description

§modalkit-ratatui

§Overview

This crate contains widgets that can be used to build modal editing TUI applications using the ratatui and modalkit crates.

§Example

The following example shows a program that opens a single textbox where the user can enter text using Vim keybindings.

For a more complete example that includes a command bar and window splitting, see examples/editor.rs in the source repository.

use modalkit::{
    actions::{Action, Editable, Jumpable, Scrollable},
    editing::{context::Resolve, key::KeyManager, store::Store},
    editing::application::EmptyInfo,
    errors::UIResult,
    env::vim::keybindings::default_vim_keys,
    key::TerminalKey,
    keybindings::BindingMachine,
};
use modalkit_ratatui::textbox::{TextBoxState, TextBox};
use modalkit_ratatui::TerminalExtOps;

use modalkit::crossterm::event::{read, Event};
use modalkit::crossterm::terminal::EnterAlternateScreen;
use ratatui::{backend::CrosstermBackend, Terminal};
use std::io::stdout;

fn main() -> UIResult<(), EmptyInfo> {
    let mut stdout = stdout();

    crossterm::terminal::enable_raw_mode()?;
    crossterm::execute!(stdout, EnterAlternateScreen)?;

    let backend = CrosstermBackend::new(stdout);
    let mut terminal = Terminal::new(backend)?;
    let mut store = Store::default();
    let mut bindings = KeyManager::new(default_vim_keys::<EmptyInfo>());
    let mut tbox = TextBoxState::new(store.load_buffer(String::from("*scratch*")));

    terminal.clear()?;

    loop {
        terminal.draw(|f| f.render_stateful_widget(TextBox::new(), f.size(), &mut tbox))?;

        if let Event::Key(key) = read()? {
            bindings.input_key(key.into());
        } else {
            continue;
        };

        while let Some((act, ctx)) = bindings.pop() {
            let store = &mut store;

            let _ = match act {
                Action::Editor(act) => tbox.editor_command(&act, &ctx, store)?,
                Action::Macro(act) => bindings.macro_command(&act, &ctx, store)?,
                Action::Scroll(style) => tbox.scroll(&style, &ctx, store)?,
                Action::Repeat(rt) => {
                    bindings.repeat(rt, Some(ctx));
                    None
                },
                Action::Jump(l, dir, count) => {
                    let _ = tbox.jump(l, dir, ctx.resolve(&count), &ctx)?;
                    None
                },
                Action::Suspend => terminal.program_suspend()?,
                Action::NoOp => None,
                _ => continue,
            };
        }
    }
}

Modules§

Traits§

  • A widget that contains content that can be converted into an action when the user is done entering text.
  • A widget whose content can be scrolled in multiple ways.
  • A widget that the user’s cursor can be placed into.
  • Extended operations for Terminal.
  • A widget that the user can open and close on the screen.
  • Trait to allow widgets to control how they get drawn onto the screen when they are either focused or unfocused.

Functions§

Type Aliases§

  • An offset from the upper-left corner of the terminal.