# keymap-rs [![crates.io](https://img.shields.io/crates/v/keymap.svg)](https://crates.io/crates/keymap) [![Rust](https://github.com/rezigned/keymap-rs/actions/workflows/ci.yml/badge.svg)](https://github.com/rezigned/keymap-rs/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-brightgreen.svg)](https://opensource.org/licenses/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](https://github.com/crossterm-rs/crossterm) or [termion](https://gitlab.redox-os.org/redox-os/termion)) ## Introduction Using terminal library's input event directly is sometimes not ideal. Let consider the following example of matching `ctrl-z` event: ```rust 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. ```toml [keys] ctrl-z = "..." ``` The `ctrl-z` above will be converted to `KeyEvent { ... }` in the first example. ## Getting started _Please check the [examples](examples/) directory for complete examples._
Click to show Cargo.toml. ```toml [dependencies] keymap = "0.1" ```
Let's started by defining a simple structure for mapping input key to `String`. ```rust use keymap::KeyMap; use serde::Deserialize; #[derive(Deserialize)] struct Config(pub HashMap) const CONFIG: &str = r#" up = "Up" down = "Down" ctrl-c = "Quit" "#; ``` Then in your terminal library of choice (we'll be using [crossterm](https://github.com/crossterm-rs/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`). ```rust 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 * [crossterm](https://github.com/crossterm-rs/crossterm) * [termion](https://gitlab.redox-os.org/redox-os/termion)