diff options
Diffstat (limited to '.config/awesome/quarrel/bind')
| -rw-r--r-- | .config/awesome/quarrel/bind/consts.lua | 27 | ||||
| -rw-r--r-- | .config/awesome/quarrel/bind/init.lua | 119 |
2 files changed, 146 insertions, 0 deletions
diff --git a/.config/awesome/quarrel/bind/consts.lua b/.config/awesome/quarrel/bind/consts.lua new file mode 100644 index 0000000..5a91d84 --- /dev/null +++ b/.config/awesome/quarrel/bind/consts.lua @@ -0,0 +1,27 @@ +local awful = require "awful" + +local C = {} + +-- taken from https://github.com/bew/dotfiles/blob/ab9bb1935783f7a31ef777b1d7e26d53f35df864/gui/wezterm/cfg_utils.lua +C.mods = setmetatable({ _SHORT_MAP = { C = "Control", S = "Shift", A = "Mod1", M = "Mod4" } }, { + __index = function(self, key) + local resolved_mods = {} + for i = 1, #key do + resolved_mods[i] = self._SHORT_MAP[key:sub(i, i)] + end + return resolved_mods + end, +}) + +local btns = awful.button.names + +---@enum buttons +C.btns = { + left = btns.LEFT, + right = btns.RIGHT, + middle = btns.MIDDLE, + up = btns.SCROLL_UP, + down = btns.SCROLL_DOWN, +} + +return C diff --git a/.config/awesome/quarrel/bind/init.lua b/.config/awesome/quarrel/bind/init.lua new file mode 100644 index 0000000..a851440 --- /dev/null +++ b/.config/awesome/quarrel/bind/init.lua @@ -0,0 +1,119 @@ +local C = require "quarrel.bind.consts" +local awful = require "awful" +local gtable = require "gears.table" + +local M = gtable.crush({ + bindings = {}, +}, C) + +---@alias mouse_button +---| 0 Left mouse button +---| 1 Middle mouse click +---| 2 Right mouse button +---| 3 Scroll up +---| 4 Scroll down + +---@alias bind +---| mouse_button +---| string + +---@alias modifier +---| "Mod1" Alt +---| "Mod4" Super +---| "Mod5" AltGr +---| "Shift" Shift +---| "Control" Ctrl + +---@class Trigger +---@field [1] bind +---@field [2] any Value passed to the press callback + +---@class Binding +---@field hidden boolean? Whether the binding shows up in the help menu +---@field mods modifier[]? Modifiers +---@field press fun(...) | fun(any, ...) Function to run when the trigger is pressed +---@field desc string? Description +---@field group string? What group the binding will show up in +---@field triggers Trigger[] | bind[] | bind + +---Get the corresponding binding creation function for a trigger +---@param bind bind +---@return string +local function get_binding_function(bind) + if type(bind) == "number" and bind <= 5 and bind > 0 then + return "button" + elseif type(bind) == "string" then + return "key" + end + error("bind can only be a mouse button or a key", 2) +end + +--- Translate a qbind binding into an awful binding +---@param binding Binding +---@param trigger Trigger | bind +---@param multi boolean specifies whether this is a multi trigger bind +---@return awful.key +local function translate_binding(binding, trigger, multi) + local awful_binding + if multi then + awful_binding = { + modifiers = binding.mods, + [get_binding_function(trigger[1])] = trigger[1], + on_press = function(...) + binding.press(trigger[2], ...) + end, + } + else + awful_binding = { + modifiers = binding.mods, + [get_binding_function(trigger --[[@as bind]])] = trigger, + on_press = binding.press, + } + end + + awful_binding.description = binding.desc + awful_binding.group = binding.group + + return awful[ + get_binding_function(multi and trigger[1] or trigger --[[@as bind]]) + ](awful_binding) +end + +--- Create a new binding +---@param binding Binding +---@return awful.key[] +function M:new(binding) + if not binding.hidden then + table.insert(self.bindings, binding) + end + binding.mods = binding.mods or {} + + local awful_bindings = {} + + if type(binding.triggers) == "table" then + for _, _trigger in + ipairs(binding.triggers --[[@as bind[] | Trigger[]]) + do + local trigger + if type(_trigger) == "table" then + trigger = _trigger + elseif type(_trigger) == "string" or type(_trigger) == "number" then + trigger = { _trigger, _trigger } + end + table.insert(awful_bindings, translate_binding(binding, trigger, true)) + end + elseif type(binding.triggers) == "string" or type(binding.triggers) == "number" then + return translate_binding(binding, binding.triggers --[[@as bind]], false) + else + error("binding.triggers can only be a string or a table (passed in " .. type(binding.triggers) .. ")") + end + + -- for some reason multi-trigger bindings only work if i do this + -- i spent a day debugging this + -- thanks awesome + return gtable.join(table.unpack(awful_bindings)) +end + +return setmetatable(M, { + __call = M.new, +}) |
