diff --git a/bindings/init.lua b/bindings/init.lua new file mode 100644 index 0000000..08cd4c8 --- /dev/null +++ b/bindings/init.lua @@ -0,0 +1,194 @@ +--[[ +-- handle key- and mousebindings in a sane and readable way +--]] + +-- needs +local awful = require("awful") +local gears = require("gears") +local notifications = require("strangesome.notifications") +local debug = notifications.debug_enabled +local debug_msg = notifications.debug_msg +local wrequire = require("strangesome.loader").wrequire + +-- define standard commands local to speed up things a little bit +local next = next +local setmetatable = setmetatable +local tonumber = tonumber + +-- strangesome.bindings +local bindings = { _NAME = "strangesome.bindings" } + +local gearstable = awful.util.table or gears.table +local internalbindings = {} +local separator = "+" +local keyregex = "([^"..separator.."]+)" + +-- define named keys with usable aliases +local named_keys = { + { "Escape", { "esc", "escape" } }, + { "Left", {} }, + { "Right", {} }, + { "Up", {} }, + { "Down", {} }, + { "Enter", {} }, + { "Return", {} }, + { "Print", {} }, + { "Space", {} }, + { "Backspace", {} }, + { "Tab", {} }, + { "XF86AudioMute", {} }, + { "XF86HomePage", {} }, + { "XF86Calculator", {} }, + { "XF86AudioMedia", {} }, + { "XF86AudioPrev", {} }, + { "XF86AudioNext", {} }, + { "XF86AudioPlay", {} }, + { "XF86AudioStop", {} }, + { "XF86MyComputer", {} }, + { "XF86AudioRaiseVolume", {} }, + { "XF86AudioLowerVolume", {} }, + -- more to come... +} + +local mod_keys = { + { "Control", { "control", "ctrl" } }, + { "Shift", {} }, + { "Mod1", { "alt", "mod1" } }, + { "Mod4", { "super", "meta", "mod4" } }, +} + +local mouse_keys = { + { 1, { "left", "mouseleft", "leftkey", "leftclick" } }, + { 2, { "middle", "mousemiddle", "middlekey", "middleclick" } }, + { 3, { "right", "mouseright", "rightkey", "rightclick" } }, + { 4, { "up", "mouseup", "scrollup" } }, + { 5, { "down", "mousedown", "scrolldown" } }, + -- more to come... +} + + +--[[ +-- map = { +-- { "Ctrl+Alt+Super+L", description, function() } +-- } +--]] + +function bindings.addkeymap(target, category, map) + if debug then debug_msg("Type of internalbindings["..target.."]: "..type(internalbindings[target])) end + if type(internalbindings[target]) == "nil" then internalbindings[target] = {} end + for _, mapentry in ipairs(map) do + local keys = mapentry[1] + local desc = mapentry[2] + local bindfunc = mapentry[3] + internalbindings[target] = gearstable.join(internalbindings[target], + awful.key(getmodkeys(keys), getkey(keys), bindfunc, {description = desc, group = category}) + ) + end + + if debug then debug_msg("Type of internalbindings["..target.."]: "..type(internalbindings[target])) end + return internalbindings[target] +end + +function bindings.addmousemap(target, map) + if debug then debug_msg("Type of internalbindings["..target.."]: "..type(internalbindings[target])) end + if type(internalbindings[target]) == "nil" then internalbindings[target] = {} end + for _, mapentry in ipairs(map) do + local keys = mapentry[1] + local bindfunc = mapentry[2] + internalbindings[target] = gearstable.join(internalbindings[target], + awful.button(getmodkeys(keys), getmousekey(keys), bindfunc) + ) + end + + if debug then debug_msg("Type of internalbindings["..target.."]: "..type(internalbindings[target])) end + return internalbindings[target] +end + +function bindings.export(target) + if type(internalbindings[target]) == "nil" then return {} end + return internalbindings[target] +end + +function getmodkeys(keys) + local modkeys = {} + local mkey + + for key in string.gmatch(keys, keyregex) do + mkey = ismodkey(key) + if mkey then + modkeys[#modkeys+1] = mkey + end + end + + return modkeys +end + +function getkey(keys) + local sepregex = "["..separator.."]["..separator.."]" + local key = "" + for str in string.gmatch(keys, keyregex) do + -- single char, always lower case + if string.len(str) == 1 then + key = string.lower(str) + -- named key, see table named_keys above + elseif isnamedkey(str) then + key = isnamedkey(str) + -- match separator key, e.g in "Alt+Super++" for Alt, Super and "+" + elseif string.match(keys, sepregex) then + key = string.lower(separator) + end + end + + return key +end + +function getmousekey(keys) + local keyregex = "([^"..separator.."]+)" + local key = 0 + local mkey + for str in string.gmatch(keys, keyregex) do + -- is number and between 1 and 5 + if type(str.tonumber) == "number" then + local num = str.tonumber + if num > 0 and num < 6 then key = num end + -- mousekey, see table mouse_keys above (integers 1 to 5) + elseif ismousekey(str) then + key = ismousekey(str) + end + end + + return key +end + +function isnamedkey(key) + -- there are no named keys with length 1 + if string.len(key) == 1 then return false end + return check_keys_table(key, named_keys) +end + +function ismodkey(key) + return check_keys_table(key, mod_keys) +end + +function ismousekey(key) + return check_keys_table(key, mouse_keys) +end + +function check_keys_table(key, table) + for _, entry in ipairs(table) do + local tkey = entry[1] + local aliases = entry[2] + if next(aliases) == nil then + --no aliases given, check against tkey + if string.lower(key) == string.lower(tkey) then return tkey end + else + for _, alias in ipairs(aliases) do + if string.lower(key) == string.lower(alias) then return tkey end + end + end + end + return false +end + + +return setmetatable(bindings, { __index = wrequire }) diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..2ea1ef9 --- /dev/null +++ b/init.lua @@ -0,0 +1,8 @@ +--[[ +-- Make awesome configuration more readable +--]] + +return { + bindings = require("strangesome.bindings"), + notifications = require("strangesome.notifications") +} diff --git a/loader.lua b/loader.lua new file mode 100644 index 0000000..3ace181 --- /dev/null +++ b/loader.lua @@ -0,0 +1,12 @@ +--[[ +-- module loader, inspired by lain +--]] +local rawget = rawget + +local loader = {} + +function loader.wrequire(t, k) + return rawget(t, k) or require(t._NAME .. '.' .. k) +end + +return loader diff --git a/notifications/init.lua b/notifications/init.lua new file mode 100644 index 0000000..2a1424d --- /dev/null +++ b/notifications/init.lua @@ -0,0 +1,65 @@ +--[[ +-- notifications and debug +--]] + +-- needs +local awful = require("awful") +local gears = require("gears") +local naughty = require("naughty") +--local addkeymap = require("strangesome.bindings").addkeymap +local wrequire = require("strangesome.loader").wrequire + +-- define standard commands local to speed up things a little bit +local setmetatable = setmetatable +local next = next + +-- strangesome.notifications +local notifications = { _NAME = "strangesome.notifications" } + +-- debug settings +local debug = false +local debug_window = nil +local debug_window_title = "Strangesome Debug Window" +local debug_text = "" +local debug_text_max_lines = 30 + +function notifications.enable_debug() + debug = true + init_debug_window() + + return debug_window +end + +function notifications.debug_enabled() + return debug +end + +function notifications.debug_msg(msg) + if not debug then return false end + debug_text = debug_text..""..msg.."\n" + naughty.replace_text(debug_window, debug_window_title, debug_text) + + return debug_text +end + +function init_debug_window() + debug_window = naughty.notify({ + title = debug_window_title, + text = "Starting Debug Window\n", + timeout = 0, + position = "bottom_right", + ontop = false, + height = 500, + width = 950, + opacity = 0.7, + ignore_suspend = true + }) + + return debug_window +end + +function toggle_debug_window() + notifications.debug_msg("Toggle debug window") +end + +return setmetatable(notifications, { __index = wrequire })