keymap

Crates.iokeymap
lib.rskeymap
version0.4.1
sourcesrc
created_at2023-07-30 08:24:26.630699
updated_at2024-11-24 02:29:57.73515
descriptionA library for parsing terminal input events from configuration
homepagehttps://github.com/rezigned/keymap-rs
repositoryhttps://github.com/rezigned/keymap-rs
max_upload_size
id929807
size44,904
rezigned (rezigned)

documentation

README

keymap-rs

crates.io Rust License: MIT

keymap-rs is a library for parsing terminal input event from configurations and mapping them to the terminal library's event. (e.g. crossterm or termion)

Introduction

Using terminal library's input event directly is sometimes not ideal. Let consider the following example of matching ctrl-z event:

match read() {
    // `ctrl-z`
    Event::Key(KeyEvent {
        modifiers: KeyModifiers::CONTROL,
        KeyCode::Char('z'),
        ..
    }) => {}
}

This code works perfectly fine. But if we want the end users to customize the key mappings to a different one (e.g. ctrl-x, shift-c, etc.). How can we achieve that? The answer is keymap.

keymap provides flexibility by allowing developers to define input event in plain-text, which can be used in any configuration formats (e.g. yaml, toml, etc.) and convert them to the terminal's event.

[keys]
ctrl-z = "..."

The ctrl-z above will be converted to KeyEvent { ... } in the first example.

Getting started

Please check the examples directory for complete examples.

Click to show Cargo.toml.
[dependencies]
keymap = "0.1"

Let's started by defining a simple structure for mapping input key to String.

use keymap::KeyMap;
use serde::Deserialize;

#[derive(Deserialize)]
struct Config(pub HashMap<KeyMap, String>)

const CONFIG: &str = r#"
up     = "Up"
down   = "Down"
ctrl-c = "Quit"
"#;

Then in your terminal library of choice (we'll be using crossterm here). You can use any deserializer (e.g. toml, json, etc.) to deserialize a key from the configuration above into the terminal library's event (e.g. crossterm::event::KeyEvent).

let config: Config = toml::from_str(CONFIG).unwrap();

// Read input event
match read()? {
    Event::Key(key) => {
        // `KeyMap::from` will convert `crossterm::event::KeyEvent` to `keymap::KeyMap`
        if let Some(action) = config.0.get(&Key::from(key)) {
            match action {
                "Up" => println!("Move up!"),
                "Down" => println!("Move down!"),
                // ...
                "Quit" => break,
            }
        }
    }
}

Supported Terminal Libraries

Commit count: 17

cargo fmt