Crate minus

source ·
Expand description

minus: A library for asynchronous terminal paging, written in Rust.

If you want to learn about its motivation and features, please take a look into it’s README.

§Overview

When getting started with minus, the two most important concepts to get familier with are:

  • The Pager type: which acts as a bridge between your application and minus. It is used to pass data and configure minus before and after starting the pager.
  • Initialization functions: This includes the dynamic_paging and page_all functions which take a Pager as argument. They are responsible for generating the initial state and starting the pager.

See the docs for the respective items to learn more on its usage.

§Examples

§Threads

use minus::{dynamic_paging, MinusError, Pager};
use std::{
    fmt::Write,
    thread::{spawn, sleep},
    time::Duration
};

fn main() -> Result<(), MinusError> {
    // Initialize the pager
    let mut pager = Pager::new();
    // Run the pager in a separate thread
    let pager2 = pager.clone();
    let pager_thread = spawn(move || dynamic_paging(pager2));

    for i in 0..=100_u32 {
        writeln!(pager, "{}", i);
        sleep(Duration::from_millis(100));
    }
    pager_thread.join().unwrap()?;
    Ok(())
}

§tokio

use minus::{dynamic_paging, MinusError, Pager};
use std::time::Duration;
use std::fmt::Write;
use tokio::{join, task::spawn_blocking, time::sleep};

#[tokio::main]
async fn main() -> Result<(), MinusError> {
    // Initialize the pager
    let mut pager = Pager::new();
    // Asynchronously send data to the pager
    let increment = async {
        let mut pager = pager.clone();
        for i in 0..=100_u32 {
            writeln!(pager, "{}", i);
            sleep(Duration::from_millis(100)).await;
        }
        Result::<_, MinusError>::Ok(())
    };
    // spawn_blocking(dynamic_paging(...)) creates a separate thread managed by the tokio
    // runtime and runs the async_paging inside it
    let pager = pager.clone();
    let (res1, res2) = join!(spawn_blocking(move || dynamic_paging(pager)), increment);
    // .unwrap() unwraps any error while creating the tokio task
    //  The ? mark unpacks any error that might have occurred while the
    // pager is running
    res1.unwrap()?;
    res2?;
    Ok(())
}

§Static output

use std::fmt::Write;
use minus::{MinusError, Pager, page_all};

fn main() -> Result<(), MinusError> {
    // Initialize a default static configuration
    let mut output = Pager::new();
    // Push numbers blockingly
    for i in 0..=30 {
        writeln!(output, "{}", i)?;
    }
    // Run the pager
    minus::page_all(output)?;
    // Return Ok result
    Ok(())
}

Note: In static mode, minus doesn’t start the pager and just prints the content if the current terminal size can display all lines. You can of course change this behaviour.

§Default keybindings

Here is the list of default key/mouse actions handled by minus.

A [n] key means that you can precede the key by an integer.

ActionDescription
Ctrl+C/qQuit the pager
[n] Arrow Up/kScroll up by n number of line(s). If n is omitted, scroll up by 1 line
[n] Arrow Down/jScroll down by n number of line(s). If n is omitted, scroll down by 1 line
Ctrl+hTurn off line wrapping and allow horizontal scrolling
[n] Arrow left/hScroll left by n number of line(s). If n is omitted, scroll up by 1 line
[n] Arrow right/lScroll right by n number of line(s). If n is omitted, scroll down by 1 line
Page UpScroll up by entire page
Page DownScroll down by entire page
[n] EnterScroll down by n number of line(s).
SpaceScroll down by one page
Ctrl+U/uScroll up by half a screen
Ctrl+D/dScroll down by half a screen
gGo to the very top of the output
[n] GGo to the very bottom of the output. If n is present, goes to that line
Mouse scroll UpScroll up by 5 lines
Mouse scroll DownScroll down by 5 lines
Ctrl+LToggle line numbers if not forced enabled/disabled
Ctrl+fToggle follow-mode
/Start forward search
?Start backward search
EscCancel search input
nGo to the next search match
pGo to the next previous match

End-applications are free to change these bindings to better suit their needs. See docs for Pager::set_input_classifier function and input module.

§Key Bindings Available at Search Prompt

Key BindingsDescription
EscCancel the search
EnterConfirm the search query
BackspaceRemove the character before the cursor
DeleteRemove the character under the cursor
Arrow LeftMove cursor towards left
Arrow rightMove cursor towards right
Ctrl+Arrow leftMove cursor towards left word by word
Ctrl+Arrow rightMove cursor towards right word by word
HomeMove cursor at the beginning pf search query
EndMove cursor at the end pf search query

Currently these cannot be changed by applications but this may be supported in the future.

Re-exports§

Modules§

  • Provides error types that are used in various places
  • Manage keyboard/mouse-bindings while running minus.
  • Provides functions for getting analysis of the text data inside minus.
  • searchsearch
    Text searching functionality
  • Contains types that hold run-time information of the pager.

Structs§

  • A communication bridge between the main application and the pager.

Enums§

  • Behaviour that happens when the pager is exited
  • Enum indicating whether to display the line numbers or not.
  • Define the modes in which minus can run

Functions§

Type Aliases§

  • A convenient type for Vec<Box<dyn FnMut() + Send + Sync + 'static>>