Macro gen_keybindings

Source
macro_rules! gen_keybindings {
    { $($tokens:tt)* } => { ... };
}
Expand description

Generate user keybindings with optional compile time validation.

§Example

let key_bindings = gen_keybindings! {
    "M-semicolon" => run_external!("dmenu_run");
    "M-Return" => run_external!("alacritty");
    "XF86AudioMute" => run_external!("amixer set Master toggle");
    "M-A-Escape" => run_internal!(exit);

    "M-j" => run_internal!(cycle_client, Forward);
    "M-k" => run_internal!(cycle_client, Backward);
    "M-S-j" => run_internal!(drag_client, Forward);
    "M-S-k" => run_internal!(drag_client, Backward);
    "M-S-q" => run_internal!(kill_client);

    "M-Tab" => run_internal!(toggle_workspace);

    "M-grave" => run_internal!(cycle_layout, Forward);
    "M-S-grave" => run_internal!(cycle_layout, Backward);
    "M-A-Up" => run_internal!(update_max_main, More);
    "M-A-Down" => run_internal!(update_max_main, Less);
    "M-A-Right" => run_internal!(update_main_ratio, More);
    "M-A-Left" => run_internal!(update_main_ratio, Less);

    map: { "1", "2", "3", "4", "5", "6", "7", "8", "9" } to index_selectors(9) => {
        "M-{}" => focus_workspace (REF);
        "M-S-{}" => client_to_workspace (REF);
    };
};

§Sections

§Direct binding

"M-j" => run_internal!(cycle_client, Forward);
"M-S-j" => run_internal!(drag_client, Forward);
"M-Return" => run_external!("alacritty");

This is what the majority of your keybindings will look like.

Should be a string literal and an expression that satisfies the KeyEventHandler type. The run_internal and run_external helper macros can be used for simplifying bindings that perform common actions like spawning external programs or triggering methods on the WindowManager.

§Map block

Bind a common pattern via a template.

// VAL: values are passed to the method directly
map: { "Up", "Down" } to vec![More, Less] => {
    "M-{}" => update_max_main (VAL);
};

// REF: values are passed to the method as references
map: { "1", "2", "3", "4", "5", "6", "7", "8", "9" } to index_selectors(9) => {
    "M-{}" => focus_workspace (REF);
    "M-S-{}" => client_to_workspace (REF);
};

When you have a common pattern for multiple key bindings (such as focusing a given workspace) you can use a map block to avoid having to write them all out explicitly. The required format is as follows:

map: { "str", "literal", "key", "names" } to `impl Iterator` => {
    "<modifiers>-{}" => `WindowManager method` ( arg, ... );
}

Note that the key names must be string literals, not just &str references. The arguments to the WindowManager method can be passed by reference using REF or by value using VAL. Any additional arguments can be passed explicitly if they are required by the method.