#key #parse #parser #编译时 #过程宏

crokey

解析并描述键 - 帮助在终端应用程序中集成快捷键

20 个版本 (3 个稳定版)

1.1.0 2024年8月12日
1.0.1 2024年6月18日
1.0.0 2024年4月24日
0.6.4 2024年3月30日
0.4.0 2022年2月7日

#58 in 命令行界面

Download history 5241/week @ 2024-05-03 3472/week @ 2024-05-10 3532/week @ 2024-05-17 3749/week @ 2024-05-24 3633/week @ 2024-05-31 3634/week @ 2024-06-07 4953/week @ 2024-06-14 5084/week @ 2024-06-21 4358/week @ 2024-06-28 5499/week @ 2024-07-05 3657/week @ 2024-07-12 3893/week @ 2024-07-19 4530/week @ 2024-07-26 3757/week @ 2024-08-02 3960/week @ 2024-08-09 4919/week @ 2024-08-16

17,750 个月下载量
35 个库中使用 (13 个直接使用)

MIT 许可证

47KB
807

MIT Latest Version docs Chat on Miaou

Crokey

Crokey 通过提供函数帮助在基于 crossterm 的终端应用程序中集成可配置的快捷键

  • 解析字符串中的键组合
  • 在字符串中描述键组合
  • 编译时解析键组合
  • 将 Crossterm 键事件组合成键组合

键组合

KeyCombination 由 1 到 3 个 "普通" 键和一些可选修饰符(alt、shift、ctrl)组成。

它可以被解析,通过 key! 宏以用户友好的方式构建,并从键事件中获取。

组合器

使用 Combiner,您可以改变原始 Crossterm 键事件为键组合。

当终端足够现代并支持 Kitty 协议时,可以形成包含最多三个非修饰键的复杂组合,例如 Ctrl-Alt-Shift-g-ySpace-!

对于标准 ANSI 终端,仅提供常规组合,如 Shift-oCtrl-Alt-Shift-gi

组合器在这两种情况下都起作用:如果您同时按下 ctrliu 键,在兼容 kitty 的终端上它将产生一个组合(ctrl-i-u),在其他终端中则假设您先按下 i 然后再按下 u,它将作为两个键组合的序列(ctrl-i 然后 ctrl-u)。

print_key 示例展示了如何处理这种情况

let fmt = KeyCombinationFormat::default();
let mut combiner = Combiner::default();
let combines = combiner.enable_combining().unwrap();
if combines {
    println!("Your terminal supports combining keys");
} else {
    println!("Your terminal doesn't support combining non-modifier keys");
}
println!("Type any key combination");
loop {
    terminal::enable_raw_mode().unwrap();
    let e = read();
    terminal::disable_raw_mode().unwrap();
    match e {
        Ok(Event::Key(key_event)) => {
            if let Some(key_combination) = combiner.transform(key_event) {
                match key_combination {
                    key!(ctrl-c) | key!(ctrl-q) => {
                        println!("quitting");
                        break;
                    }
                    _ => {
                        println!("You typed {}", fmt.to_string(key_combination));
                    }
                }
            }
        },
        ...
    }
}

解析字符串

这些字符串通常由配置文件提供。

use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
assert_eq!(
    crokey::parse("alt-enter").unwrap(),
    KeyEvent::new(KeyCode::Enter, KeyModifiers::ALT),
);
assert_eq!(
    crokey::parse("shift-F6").unwrap(),
    KeyEvent::new(KeyCode::F(6), KeyModifiers::SHIFT),
);

使用过程宏通过键组合 "字面量"

这些键组合在编译时解析,且运行时成本为零。

它们效率高且方便,用于匹配事件或定义硬编码的快捷键。

match key_event.into() {
    key!(ctrl-c) => {
        println!("Arg! You savagely killed me with a {}", fmt.to_string(key_event).red());
        break;
    }
    key!(ctrl-q) => {
        println!("You typed {} which gracefully quits", fmt.to_string(key_event).green());
        break;
    }
    _ => {
        println!("You typed {}", fmt.to_string(key_event).blue());
    }
}

完整示例在 /examples/print_key

print_key

可以在常量上下文中调用 key!

const quit: KeyCombination = key!(ctrl-q);

以可配置的格式显示字符串

use crokey::*;
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};

// The default format
let format = KeyCombinationFormat::default();
assert_eq!(format.to_string(key!(shift-a)), "Shift-a");
assert_eq!(format.to_string(key!(ctrl-c)), "Ctrl-c");

// A more compact format
let format = KeyCombinationFormat::default()
    .with_implicit_shift()
    .with_control("^");
assert_eq!(format.to_string(key!(shift-a)), "A");
assert_eq!(format.to_string(key!(ctrl-c)), "^c");

使用 Serde 反序列化快捷键绑定

启用 "serde" 功能后,您可以以直接方式读取配置文件

use {
    crokey::*,
    crossterm::event::KeyEvent,
    serde::Deserialize,
    std::collections::HashMap,
};
#[derive(Debug, Deserialize)]
struct Config {
    keybindings: HashMap<KeyCombination, String>,
}
static CONFIG_HJSON: &str = r#"
{
    keybindings: {
        a: aardvark
        shift-b: babirussa
        ctrl-k: koala
        alt-j: jaguar
    }
}
"#;
let config: Config = deser_hjson::from_str(CONFIG_HJSON).unwrap();
let key: KeyCombination = key!(shift-b);
assert_eq!(
    config.keybindings.get(&key).unwrap(),
    "babirussa",
);

您可以使用任何 Serde 兼容的格式,例如 JSON 或 TOML。

Crossterm 兼容性

Crokey 包含并重新导出 Crossterm,因此您无需导入它,以避免冲突。

依赖关系

~4–12MB
~165K SLoC