aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/quarrel/bind/init.lua
diff options
context:
space:
mode:
Diffstat (limited to '.config/awesome/quarrel/bind/init.lua')
-rw-r--r--.config/awesome/quarrel/bind/init.lua119
1 files changed, 119 insertions, 0 deletions
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,
+})