aboutsummaryrefslogtreecommitdiff
path: root/.config/awesome/quarrel/bind
diff options
context:
space:
mode:
authordelta <darkussdelta@gmail.com>2025-07-04 00:38:29 +0200
committerdelta <darkussdelta@gmail.com>2025-07-04 00:38:29 +0200
commitb3530d7c4a102935fa26498a160ee1dc6c1e9c03 (patch)
treed7751206a694bc5de2d6b34b0c077cfcd1855798 /.config/awesome/quarrel/bind
parentdf75ec5ed5e3848c497f0439acb43ec9246ad3e7 (diff)
:3
Diffstat (limited to '.config/awesome/quarrel/bind')
-rw-r--r--.config/awesome/quarrel/bind/consts.lua27
-rw-r--r--.config/awesome/quarrel/bind/init.lua119
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,
+})