/awesome-wm-hydra

Multi-key-sequence framework for AwesomeWM with key hints display.

Primary LanguageLuaMIT LicenseMIT

awesome-wm-hydra

Multi-key-sequence framework for AwesomeWM with key hints display.

It allows you to bind action to a sequence of any number of keys, such as Super + w + c. The sequence resets only when the initial Super is released, allowing you to easily implement modal bindings, such as pressing Super + m for music-related keys then press h/l multiple-times for seeking while holding down Super.

This supercharges your AwesomeWM key bindings by allowing you to control an infinite number of actions through the keyboard without having to remember them all.

Screenshot 1 Screenshot 2 Screenshot 3

Getting started

  • Clone this repository to your AwesomeWM configuration directory:
    git clone https://github.com/TommyX12/awesome-wm-hydra.git ~/.config/awesome/awesome-wm-hydra
  • Require the module in your rc.lua:
    local hydra = require("awesome-wm-hydra")
  • Write hydra key binding configs somewhere in your setup. Example (describe bindings that are active after pressing left super key):
    local super_key_bindings = {
        ["return"] = {"open a terminal", function() awful.spawn(terminal) end},
        ["control-r"] = {"reload awesome", awesome.restart},
        ["j"] = {"focus down", function()
            awful.client.focus.bydirection("down")
            if client.focus then client.focus:raise() end
        end},
        ["r"] = {"run application", function()
            awful.spawn('rofi -show drun')
        end},
        ["w"] = {"window control", {
            ["c"] = {"clear notifications", function()
                naughty.destroy_all_notifications()
            end},
            ["m"] = {"maximization control", {
                ["m"] = {"toggle maximize", function()
                    local c = client.focus
                    if not c then return end
                    c.maximized = not c.maximized
                    c:raise()
                end},
            }}
        }}
    }
  • Trigger hydra in your main awesome key bindings. Example (trigger when left super key is pressed):
    awful.key({}, "Super_L", function ()
        hydra.start {
            activation_key = "Super_L",
            ignored_mod = "Mod4",
            config = super_key_bindings,
        }
    end),
  • Hydra will display dynamic key hints when the activation key is pressed, and will be updated to show keys at the active level. The key hint can be configured to only show at second level and below.

Configuration

Key bindings

The key binding config is a nested table, where each table key is a key ID (see below), and each corresponding value is an array with two elements:

  1. A string describing the key.
  2. Either:
    • A function to be called when the key is pressed. After pressing the key, this function will be called, and hydra will stay in this level of the key binding config so that other keys at this level can be pressed again as long as the activation key is still held down.
    • A nested config table with the same structure as described above. After pressing the key, hydra will go into this level of the key binding config, and the key hints will be updated to show the keys at this level.

Since this is a plain Lua table, you can define the key binding config in any way you like, such as programmatically generating bindings:

for i = 1, 9 do
    super_key_bindings[tostring(i)] = {
        "view tag " .. i,
        function()
            local tag = awful.screen.focused().tags[i]
            if tag then
                tag:view_only()
            end
        end
    }
end

Key ID

A key ID is a string that represents a key (along with modifiers). Every modifier + key combination has a unique key ID.

  • The key ID is a lower case string consists of dash-separated modifiers and the key itself (e.g. control-a, control-shift-a, mod1-space).
  • Modifiers are control, shift, mod1 (alt), or mod4 (super), and they must appear in sorted order (e.g. control before shift).
  • The key itself is the key name, such as a, b, 1, space, return, etc. Note that when shift is active, the key name is the shifted key name (e.g. ! instead of 1), except for alphabets (where they are always lowercase).
  • Because every modifier + key combination has a unique key ID, be sure to double-check the key ID when defining key bindings.

Hiding key from key hints

Use hydra.hidden as the description string to hide the key from key hints. This is useful when there are multiple similar keys such as 1, 2, 3, etc., and you only want to show the hint for 1.

Main trigger arguments

Here are the arguments for the hydra.start function:

  • Required arguments:
    • activation_key: The trigger key. This is not a key ID, but a AwesomeWM key name. This must match the key used in your awesome key config to trigger hydra, since it's used to detect when the activation key is released.
    • config: The key binding config table.
  • Optional arguments:
    • ignored_mod: The modifier to ignore when detecting the activation key. This is not a key ID, but a AwesomeWM modifier name. This is useful when the activation key is a modifier key, such as Mod4 (super key), so that the activation key itself does not have to be specified in the key binding config.
    • hide_first_level: Whether to hide the key hints at the first level. Defaults to false.
  • Key hint theme customizations:
    • key_fg: The foreground color of the keys.
    • key_bg: The background color of the keys.
    • key_control_fg: The foreground color of the control modifier.
    • key_shift_fg: The foreground color of the shift modifier.
    • key_modifier_fg: The foreground color of the alt and super modifiers.
    • activation_fg: The foreground color of the activation key.
    • nested_fg: The foreground color of hints that point to nested levels.
    • nested_bg: The background color of hints that point to nested levels.
    • focused_fg: The foreground color of the key that just got pressed.
    • focused_bg: The background color of the key that just got pressed.