Configurable keybindings

This commit is contained in:
Yessiest 2022-09-04 14:25:18 +04:00
parent 25ec8689f3
commit ab0c30f719
6 changed files with 245 additions and 24 deletions

31
desktop.conf Normal file
View File

@ -0,0 +1,31 @@
# Global variables
[global]
terminal = "$HOME/.local/bin/st"
browser = "prime-run librewolf"
modkey = "Mod4"
theme = "reno98"
shell = "zsh"
# Keybindings
# Format: <modifier>(+<modifier>+...)+<key> = "<command or :internal.function>"
# "modkey" as modifier will be substituted for modkey variable in [global]
[keys]
modkey+Up = ":root.client_next"
modkey+Down = ":root.client_previous"
modkey+Control+Up = ":root.screen_next"
modkey+Control+Down = ":root.screen_previous"
modkey+Tab = ":root.client_swap"
modkey+Return = ":root.spawn_terminal"
modkey+Shift+Return = ":root.spawn_browser"
# Client keys only work if a focused client exists
modkey+Shift+c = ":client.kill"
modkey+t = ":client.cycle_screen"
modkey+o = ":client.ontop"
modkey+b = ":client.below"
modkey+f = ":client.fullscreen"
modkey+n = ":client.minimize"
modkey+m = ":client.maximize"
# Custom keys
modkey+v = "notify-send test"

47
libs/parser_test.lua Normal file
View File

@ -0,0 +1,47 @@
-- This file is part of Reno desktop.
--
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
--
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
local parsers = require("parsers")
-- Conf parser
local data = [[
# Global variables
[global]
terminal = "$HOME/.local/bin/st"
browser = "prime-run librewolf"
modkey = "Mod4"
theme = "reno98"
shell = "zsh"
# Keybindings
# Format: <modifier>(+<modifier>+...)+<key> = "<command or :internal.function>"
# "modkey" as modifier will be substituted for modkey variable in [global]
[keys]
modkey+Up = ":root.client_next"
modkey+Down = ":root.client_previous"
modkey+Control+Up = ":root.screen_next"
modkey+Control+Down = ":root.screen_previous"
modkey+Tab = ":root.client_swap"
modkey+Return = ":root.spawn_terminal"
modkey+Shift+Return = ":root.spawn_browser"
# Client keys only work if a focused client exists
modkey+Shift+c = ":client.kill"
modkey+t = ":client.cycle_screen"
modkey+o = ":client.ontop"
modkey+b = ":client.below"
modkey+f = ":client.fullscreen"
modkey+n = ":client.minimize"
modkey+m = ":client.maximize"
]]
for k,v in pairs(parsers.conf(data)) do
print("Block: ["..k.."]")
for kk,vv in pairs(v) do
print(kk,vv)
end
end

82
libs/parsers.lua Normal file
View File

@ -0,0 +1,82 @@
-- This file is part of Reno desktop.
--
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
--
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
-- Various utilitiy parsers
local parsers = {}
local function split_strings(text)
-- probably the cleanest function to split by strings i've written
local split = {}
while text:find("\"") do
local strstart = text:find("\"")
while text:sub(strstart-1,strstart-1) == "\\" do
strstart = text:find("\"",strstart+1)
end
local strend = text:find("\"",strstart+1)
while text:sub(strend-1,strend-1) == "\\" do
strend = text:find("\"",strend+1)
end
if not strend then
return nil, "String not closed at "..strstart
end
local before_string = text:sub(1,strstart-1)
local string = text:sub(strstart,strend):gsub("\\\"","\"")
text = text:sub(strend+1,-1)
table.insert(split,before_string)
table.insert(split,string)
end
table.insert(split,text)
return split
end
parsers.conf = function(cfgtext)
cfgtext = cfgtext:gsub("#[^\n]*","")
local split_by_strings,err = split_strings(cfgtext)
if not split_by_strings then
error(err)
end
local struct = {global = {}}
local block = "global"
local last_string_key = nil
local err
for k,v in pairs(split_by_strings) do
if not v:match("^\".*\"$") then
v:gsub("[^\n]*",function(line)
-- Nothing
if line:match("^%s*$") then
return
end
-- Namespace block
if line:match("^%s*%[[^%]]-%]%s*$") then
block = line:match("%[([^%]]-)%]")
struct[block] = {}
return
end
-- String/Multiline string assignment
if line:match("^%s*[^=]-%s*=%s*$") then
last_string_key = line:match("^%s*([^=]-)%s*=%s*$")
return
end
-- Number/boolean assignment
local key,value = line:match("^%s*([^=]-)%s*=%s*(.-)%s*$")
-- number
if value:match("^[%d%.]*$") then
value = tonumber(value)
-- bool
elseif (value:lower() == "yes") or (value:lower() == "no") then
value = (value:lower() == "yes")
end
struct[block][key] = value
end)
else
struct[block][last_string_key] = v:sub(2,-2)
end
end
return struct
end
return parsers

16
libs/utils.lua Normal file
View File

@ -0,0 +1,16 @@
-- This file is part of Reno desktop.
--
-- Reno desktop is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
--
-- Reno desktop is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
-- Various utilities that are not included into awesomewm
local utils = {}
utils.substitute_env = function(str)
return str:gsub("$[%w_]+",function(var)
return os.getenv(var:sub(2,-1)) or ""
end)
end
return utils

View File

@ -8,30 +8,62 @@
-- Module that adds default keybindings
local awful = require("awful")
local gears = require("gears")
global.modkey = global.modkey or "Mod4"
local function get_keycomb(name)
local modifiers = {}
name = name:gsub("[^%s%+]+%+",function(v)
if v == "modkey+" then v = global.modkey.."+" end
table.insert(modifiers,v:sub(1,-2))
return ""
end)
return modifiers,name
end
local keymap = keybindings
local function k(name,callback,description)
if not keymap[name] then
return {}
end
local modifiers,key = get_keycomb(keymap[name])
return awful.key(modifiers,key,
callback,
description)
end
local custom_keys = {}
for comm,bind in pairs(keymap) do
if not comm:match("^:.*") then
table.insert(custom_keys,k(comm,function()
awful.spawn(comm)
end,{description = bind, group = "custom"}))
end
end
local keys = gears.table.join(
awful.key({global.modkey}, "Up",
k(':root.client_next',
function()
awful.client.focus.byidx(1)
end,
{description = "switch to next client", group = "client"}),
awful.key({global.modkey}, "Down",
k(":root.client_previous",
function()
awful.client.focus.byidx(-1)
end,
{description = "switch to previous client", group = "client"}),
awful.key({global.modkey, "Control"}, "Up",
k(":root.screen_next",
function()
awful.screen.focus_relative(1)
end,
{description = "switch to next screen", group = "screen"}),
awful.key({global.modkey, "Control"}, "Down",
k(":root.screen_previous",
function()
awful.screen.focus_relative(-1)
end,
{description = "switch to previous screen", group = "screen"}),
awful.key({global.modkey}, "Tab",
k(":root.client_swap",
function()
awful.client.focus.history.previous()
if client.focus then
@ -39,16 +71,17 @@ local keys = gears.table.join(
end
end,
{description = "go back", group = "client"}),
awful.key({global.modkey}, "Return",
k(":root.spawn_terminal",
function()
awful.spawn(global.terminal)
end,
{description = "Open terminal", group = "launcher"}),
awful.key({global.modkey, "Shift"}, "Return",
{description = "open terminal", group = "launcher"}),
k(":root.spawn_browser",
function()
awful.spawn(global.browser)
end,
{description = "Open browser", group = "launcher"}))
{description = "open browser", group = "launcher"}),
table.unpack(custom_keys))
root.keys(keys)
local buttons = gears.table.join(
@ -59,38 +92,38 @@ local buttons = gears.table.join(
root.buttons(buttons)
local clientkeys = gears.table.join(
awful.key({global.modkey, "Shift"},"c",
k(":client.kill",
function(c)
c:kill()
end,
{description = "close client", group = "client"}),
awful.key({global.modkey}, "o",
k(":client.cycle_screen",
function(c)
c:move_to_screen()
end,
{description = "move to screen", group = "client"}),
awful.key({global.modkey}, "t",
k(":client.ontop",
function(c)
c.ontop = not c.ontop
end,
{description = "toggle ontop", group = "client"}),
awful.key({global.modkey}, "b",
k(":client.below",
function(c)
c.below = not c.below
end,
{description = "toggle below", group = "client"}),
awful.key({global.modkey}, "f",
k(":client.fullscreen",
function(c)
c.fullscreen = not c.fullscreen
c:raise()
end,
{description = "toggle fullscreen", group = "client"}),
awful.key({ global.modkey }, "n",
k(":client.minimize",
function (c)
c.minimized = true
end ,
{description = "minimize", group = "client"}),
awful.key({ global.modkey }, "m",
k(":client.maximize",
function (c)
c.maximized = not c.maximized
c:raise()

View File

@ -6,10 +6,22 @@
--
-- You should have received a copy of the GNU General Public License along with Reno desktop. If not, see <https://www.gnu.org/licenses/>.
-- Global settings
global = {}
global.terminal = os.getenv("HOME").."/.local/bin/st" --Mod+Enter (spawn terminal)
global.browser = "prime-run librewolf" --Mod+Shift+Enter (spawn browser)
global.modkey = "Mod4" -- Default modifier key
global.theme = "reno98"
global.shell = "zsh"
local conf = require("parsers").conf
local envsub = require("utils").substitute_env
local conf_file = io.open(root_path.."/desktop.conf","r")
if not conf_file then
error("desktop.conf is missing or not readable")
end
local config = conf(conf_file:read("*a"))
conf_file:close()
global = config.global
global.terminal = envsub(global.terminal)
global.browser = envsub(global.browser)
local function invert(t)
local new_t = {}
for k,v in pairs(t) do
new_t[v] = k
end
return new_t
end
keybindings = invert(config.keys)