option to define vim and tmux keybinds

This commit is contained in:
BZ 2023-09-18 12:10:39 +02:00
parent e448723a09
commit 161eb45b1a
1 changed files with 181 additions and 117 deletions

162
init.lua
View File

@ -3,98 +3,163 @@ local glib = require("lgi").GLib
local unpack = unpack or table.unpack -- luacheck: globals unpack local unpack = unpack or table.unpack -- luacheck: globals unpack
local module = {} local module = {}
local change_mods = function(current, next)
local intersect = {}
-- determine mods that needs to be released
for _, c in ipairs(current) do
local is_unique = true
for _, n in ipairs(next) do
if string.upper(c) == string.upper(n) then
is_unique = false
break
end
end
if is_unique then
root.fake_input("key_release", c)
else
intersect[#intersect + 1] = c
end
end
-- determine mods that needs to be pressed
for _, n in ipairs(next) do
local is_unique = true
for _, i in ipairs(intersect) do
if string.upper(n) == string.upper(i) then
is_unique = false
break
end
end
if is_unique then
root.fake_input("key_press", n)
end
end
end
local function new(args) local function new(args)
local awesome, client, root, keygrabber = awesome, client, root, keygrabber -- luacheck: awesome globals client root keygrabber local awesome, client, root, keygrabber = awesome, client, root, keygrabber -- luacheck: awesome globals client root keygrabber
local keys = args or {up = {"k", "Up"}, down = {"j", "Down"}, left = {"h", "Left"}, right = {"l", "Right"}} local cfg = args
or { up = { "k", "Up" }, down = { "j", "Down" }, left = { "h", "Left" }, right = {
"l",
"Right",
} }
local mod = keys.mod or "Mod4" local mod = cfg.mod or "Mod4"
local mod_keysym = keys.mod_keysym or "Super_L" local mod_keysym = cfg.mod_keysym or "Super_L"
local focus = keys.focus or awful.client.focus.global_bydirection local focus = cfg.focus or awful.client.focus.global_bydirection
local wm_keys = {
mods = { mod_keysym },
up = cfg.up,
down = cfg.down,
left = cfg.left,
right = cfg.right,
}
local tmux_keys = cfg.tmux
or {
mods = { "Control_L" },
up = "Up",
down = "Down",
left = "Left",
right = "Right",
}
local vim_keys = cfg.vim or {
mods = { "Control_L" },
up = "k",
down = "j",
left = "h",
right = "l",
}
local switch_mods_fn = function(current_mods, next_mods, fn, dir)
keygrabber.stop()
change_mods(current_mods, next_mods)
fn(dir)
change_mods(next_mods, current_mods)
end
local tmux = {} local tmux = {}
tmux.left = function() tmux.left = function()
root.fake_input("key_release", "Left") root.fake_input("key_release", tmux_keys.left)
root.fake_input("key_press", "Left") root.fake_input("key_press", tmux_keys.left)
root.fake_input("key_release", "Left") root.fake_input("key_release", tmux_keys.left)
end end
tmux.right = function() tmux.right = function()
root.fake_input("key_release", "Right") root.fake_input("key_release", tmux_keys.right)
root.fake_input("key_press", "Right") root.fake_input("key_press", tmux_keys.right)
root.fake_input("key_release", "Right") root.fake_input("key_release", tmux_keys.right)
end end
tmux.up = function() tmux.up = function()
root.fake_input("key_release", "Up") root.fake_input("key_release", tmux_keys.up)
root.fake_input("key_press", "Up") root.fake_input("key_press", tmux_keys.up)
root.fake_input("key_release", "Up") root.fake_input("key_release", tmux_keys.up)
end end
tmux.down = function() tmux.down = function()
root.fake_input("key_release", "Down") root.fake_input("key_release", tmux_keys.down)
root.fake_input("key_press", "Down") root.fake_input("key_press", tmux_keys.down)
root.fake_input("key_release", "Down") root.fake_input("key_release", tmux_keys.down)
end end
local tmux_navigate = function(dir) local tmux_navigate = function(dir)
keygrabber.stop()
root.fake_input("key_release", mod_keysym)
root.fake_input("key_press", "Control_L")
tmux[dir]() tmux[dir]()
root.fake_input("key_release", "Control_L")
root.fake_input("key_press", mod_keysym)
end end
local vim = {} local vim = {}
vim.left = function() vim.left = function()
root.fake_input("key_release", "h") root.fake_input("key_release", vim_keys.left)
root.fake_input("key_press", "h") root.fake_input("key_press", vim_keys.left)
root.fake_input("key_release", "h") root.fake_input("key_release", vim_keys.left)
end end
vim.right = function() vim.right = function()
root.fake_input("key_release", "l") root.fake_input("key_release", vim_keys.right)
root.fake_input("key_press", "l") root.fake_input("key_press", vim_keys.right)
root.fake_input("key_release", "l") root.fake_input("key_release", vim_keys.right)
end end
vim.up = function() vim.up = function()
root.fake_input("key_release", "k") root.fake_input("key_release", vim_keys.up)
root.fake_input("key_press", "k") root.fake_input("key_press", vim_keys.up)
root.fake_input("key_release", "k") root.fake_input("key_release", vim_keys.up)
end end
vim.down = function() vim.down = function()
root.fake_input("key_release", "j") root.fake_input("key_release", vim_keys.down)
root.fake_input("key_press", "j") root.fake_input("key_press", vim_keys.down)
root.fake_input("key_release", "j") root.fake_input("key_release", vim_keys.down)
end end
local vim_navigate = function(dir) local vim_navigate = function(dir)
keygrabber.stop()
root.fake_input("key_release", mod_keysym)
root.fake_input("key_release", "Control_L")
root.fake_input("key_press", "Control_L")
vim[dir]() vim[dir]()
root.fake_input("key_release", "Control_L")
root.fake_input("key_press", mod_keysym)
end end
-- use dynamic titles to determine type of client (default) -- use dynamic titles to determine type of client (default)
local navigate = function(dir) local navigate = function(dir)
local c = client.focus local c = client.focus
local client_name = c and c.name or "" local client_name = c and c.name or ""
if string.find(client_name, "- N?VIM$") then if string.find(client_name, "%- N?VIM$") then
return vim_navigate(dir) switch_mods_fn(wm_keys.mods, vim_keys.mods, vim_navigate, dir)
elseif string.find(client_name, "- TMUX$") then return
return tmux_navigate(dir) elseif string.find(client_name, "%- TMUX$") then
switch_mods_fn(wm_keys.mods, tmux_keys.mods, tmux_navigate, dir)
return
else else
focus(dir) focus(dir)
end end
end end
-- use pstree to determine type of client (experimental) -- use pstree to determine type of client (experimental)
if keys.experimental then if cfg.experimental then
navigate = function(dir) navigate = function(dir)
local c = client.focus local c = client.focus
local pid = c and c.pid or -1 local pid = c and c.pid or -1
awful.spawn.easy_async("pstree -A -T " .. pid, function(out) awful.spawn.easy_async("pstree -A -T " .. pid, function(out)
if string.find(out, "[^.*\n]%-tmux: client") then if string.find(out, "[^.*\n]%-tmux: client") then
return tmux_navigate(dir) return tmux_navigate(dir)
elseif string.find(out, "[^.*\n]%-n?vim$") or string.find(out, "[^.*\n]%-n?vim%-") or elseif
string.find(out, "^gvim$") or string.find(out, "^gvim%-") then string.find(out, "[^.*\n]%-n?vim$")
or string.find(out, "[^.*\n]%-n?vim%-")
or string.find(out, "^gvim$")
or string.find(out, "^gvim%-")
then
return vim_navigate(dir) return vim_navigate(dir)
else else
focus(dir) focus(dir)
@ -110,7 +175,7 @@ local function new(args)
-- setup keybinds -- setup keybinds
glib.idle_add(glib.PRIORITY_DEFAULT_IDLE, function() glib.idle_add(glib.PRIORITY_DEFAULT_IDLE, function()
local aw = {} local aw = {}
for k, v in pairs(keys) do for k, v in pairs(cfg) do
for _, dir in pairs({ "left", "right", "up", "down" }) do for _, dir in pairs({ "left", "right", "up", "down" }) do
if k == dir then if k == dir then
for _, key_name in ipairs(v) do for _, key_name in ipairs(v) do
@ -121,7 +186,6 @@ local function new(args)
break break
end end
end end
end end
root.keys(awful.util.table.join(root.keys(), unpack(aw))) root.keys(awful.util.table.join(root.keys(), unpack(aw)))
end) end)
@ -131,5 +195,5 @@ end
return setmetatable(module, { return setmetatable(module, {
__call = function(_, ...) __call = function(_, ...)
return new(...) return new(...)
end end,
}) })