256 lines
10 KiB
Lua
256 lines
10 KiB
Lua
local keymap = require 'keyboard.keymaps'
|
|
|
|
local yabai_cmd = '/etc/profiles/per-user/rayandrew/bin/yabai'
|
|
local jq_cmd = '/etc/profiles/per-user/rayandrew/bin/jq'
|
|
|
|
local function yabai_query(query, jq_filter)
|
|
local cmd = yabai_cmd .. ' -m query ' .. query
|
|
if jq_filter then cmd = cmd .. ' | ' .. jq_cmd .. ' ' .. jq_filter end
|
|
local handle = io.popen(cmd)
|
|
local result = handle:read('*a'):gsub('%s+', '')
|
|
handle:close()
|
|
return result
|
|
end
|
|
|
|
local function yabai(commands, logic)
|
|
local cmd_string = ''
|
|
for i, cmd in ipairs(commands) do
|
|
if i == 1 then
|
|
cmd_string = yabai_cmd .. ' -m ' .. cmd
|
|
else
|
|
if logic == 'and' then
|
|
cmd_string = cmd_string .. ' && ' .. yabai_cmd .. ' -m ' .. cmd
|
|
elseif logic == 'or' then
|
|
cmd_string = cmd_string .. ' || ' .. yabai_cmd .. ' -m ' .. cmd
|
|
else
|
|
cmd_string = cmd_string .. ' ; ' .. yabai_cmd .. ' -m ' .. cmd
|
|
end
|
|
end
|
|
end
|
|
os.execute(cmd_string)
|
|
end
|
|
|
|
local function yabai_key(opts)
|
|
keymap.super {
|
|
key = opts.key,
|
|
mods = opts.mods,
|
|
message = opts.message,
|
|
fn = function() yabai(opts.commands, opts.logic) end,
|
|
}
|
|
end
|
|
|
|
keymap.super {
|
|
key = 'return',
|
|
-- message = "Spawn Ghostty",
|
|
fn = function()
|
|
-- hs.application.launchOrFocus("Ghostty")
|
|
-- hs.timer.doAfter(0.1, function()
|
|
-- hs.eventtap.keyStroke({ "cmd" }, "n")
|
|
-- end)
|
|
os.execute 'open -na Ghostty'
|
|
end,
|
|
}
|
|
|
|
yabai_key { key = 'f', commands = { 'window --toggle zoom-fullscreen' } }
|
|
yabai_key { key = 'l', commands = { 'space --focus recent' } }
|
|
yabai_key { key = 'm', commands = { 'space --toggle mission-control' } }
|
|
yabai_key { key = 'p', commands = { 'window --toggle pip' } }
|
|
yabai_key { key = 'g', commands = { 'space --toggle padding', 'space --toggle gap' } }
|
|
yabai_key { key = 'r', commands = { 'space --rotate 90' } }
|
|
yabai_key { key = 'space', commands = { 'window --toggle float', 'window --grid 4:4:1:1:2:2' } }
|
|
|
|
yabai_key { key = "'", commands = { 'space --layout stack' } }
|
|
yabai_key { key = ';', commands = { 'space --layout bsp' } }
|
|
yabai_key { key = 'tab', commands = { 'space --focus recent' } }
|
|
|
|
-- toggle between bsp and stack layout
|
|
keymap.super {
|
|
key = 's',
|
|
message = 'Toggle layout (bsp/stack)',
|
|
fn = function()
|
|
local current_type = yabai_query('--spaces --space', "'.type'")
|
|
local new_layout = current_type == 'bsp' and 'stack' or 'bsp'
|
|
os.execute(yabai_cmd .. ' -m space --layout ' .. new_layout)
|
|
end,
|
|
}
|
|
|
|
-- navigation
|
|
yabai_key { key = 'h', commands = { 'window --focus west', 'display --focus west' }, logic = 'or' }
|
|
yabai_key { key = 'j', commands = { 'window --focus south', 'display --focus south' }, logic = 'or' }
|
|
yabai_key { key = 'k', commands = { 'window --focus north', 'display --focus north' }, logic = 'or' }
|
|
yabai_key { key = 'l', commands = { 'window --focus east', 'display --focus east' }, logic = 'or' }
|
|
|
|
-- move windows (swap within space, or move to adjacent display if at edge)
|
|
yabai_key { mods = { 'shift' }, key = 'h', commands = { 'window --swap west', 'window --display west', 'display --focus west' }, logic = 'or' }
|
|
yabai_key { mods = { 'shift' }, key = 'j', commands = { 'window --swap south', 'window --display south', 'display --focus south' }, logic = 'or' }
|
|
yabai_key { mods = { 'shift' }, key = 'k', commands = { 'window --swap north', 'window --display north', 'display --focus north' }, logic = 'or' }
|
|
yabai_key { mods = { 'shift' }, key = 'l', commands = { 'window --swap east', 'window --display east', 'display --focus east' }, logic = 'or' }
|
|
|
|
-- spaces - focus space and its display
|
|
local function focus_space(space_num)
|
|
local display = yabai_query('--spaces', "'.[] | select(.index == " .. space_num .. ") | .display'")
|
|
|
|
if display and display ~= '' then
|
|
os.execute(yabai_cmd .. ' -m display --focus ' .. display)
|
|
hs.timer.usleep(50000) -- 50ms delay
|
|
end
|
|
|
|
os.execute(yabai_cmd .. ' -m space --focus ' .. space_num)
|
|
end
|
|
|
|
keymap.super { key = '1', fn = function() focus_space(1) end }
|
|
keymap.super { key = '2', fn = function() focus_space(2) end }
|
|
keymap.super { key = '3', fn = function() focus_space(3) end }
|
|
keymap.super { key = '4', fn = function() focus_space(4) end }
|
|
keymap.super { key = '5', fn = function() focus_space(5) end }
|
|
keymap.super { key = '6', fn = function() focus_space(6) end }
|
|
keymap.super { key = '7', fn = function() focus_space(7) end }
|
|
keymap.super { key = '8', fn = function() focus_space(8) end }
|
|
keymap.super { key = '9', fn = function() focus_space(9) end }
|
|
keymap.super { key = '0', fn = function() focus_space(10) end }
|
|
|
|
-- move window to space and follow
|
|
yabai_key { mods = { 'shift' }, key = '1', commands = { 'window --space 1', 'space --focus 1' } }
|
|
yabai_key { mods = { 'shift' }, key = '2', commands = { 'window --space 2', 'space --focus 2' } }
|
|
yabai_key { mods = { 'shift' }, key = '3', commands = { 'window --space 3', 'space --focus 3' } }
|
|
yabai_key { mods = { 'shift' }, key = '4', commands = { 'window --space 4', 'space --focus 4' } }
|
|
yabai_key { mods = { 'shift' }, key = '5', commands = { 'window --space 5', 'space --focus 5' } }
|
|
yabai_key { mods = { 'shift' }, key = '6', commands = { 'window --space 6', 'space --focus 6' } }
|
|
yabai_key { mods = { 'shift' }, key = '7', commands = { 'window --space 7', 'space --focus 7' } }
|
|
yabai_key { mods = { 'shift' }, key = '8', commands = { 'window --space 8', 'space --focus 8' } }
|
|
yabai_key { mods = { 'shift' }, key = '9', commands = { 'window --space 9', 'space --focus 9' } }
|
|
yabai_key { mods = { 'shift' }, key = '0', commands = { 'window --space 10', 'space --focus 10' } }
|
|
|
|
-- move current space between displays
|
|
yabai_key { mods = { 'ctrl' }, key = 'h', message = 'Move space to left display', commands = { 'space --display west' } }
|
|
yabai_key { mods = { 'ctrl' }, key = 'l', message = 'Move space to right display', commands = { 'space --display east' } }
|
|
|
|
-- create new space and move window to it
|
|
-- keymap.super {
|
|
-- key = 'n',
|
|
-- mods = { 'shift' },
|
|
-- message = 'Create new space and move window',
|
|
-- fn = function()
|
|
-- os.execute(yabai_cmd .. ' -m space --create')
|
|
-- hs.timer.usleep(100000) -- 100ms
|
|
--
|
|
-- local index = yabai_query('--spaces --display', '\'map(select(."is-native-fullscreen" == false))[-1].index\'')
|
|
--
|
|
-- if index and index ~= '' then
|
|
-- os.execute(yabai_cmd .. ' -m window --space ' .. index)
|
|
-- os.execute(yabai_cmd .. ' -m space --focus ' .. index)
|
|
-- end
|
|
-- end,
|
|
-- }
|
|
|
|
-- split type - use insert direction to control next window placement
|
|
-- yabai_key { key = 'v', commands = { 'window --insert east' } }
|
|
-- yabai_key { mods = { 'shift' }, key = 'v', commands = { 'window --insert south' } }
|
|
|
|
yabai_key { key = 'v', commands = { 'config split_type vertical' } }
|
|
yabai_key { mods = { 'shift' }, key = 'v', commands = { 'config split_type horizontal' } }
|
|
|
|
-- Resize mode
|
|
local resize_mode = hs.hotkey.modal.new()
|
|
|
|
-- Function to show resize mode indicator
|
|
function resize_mode:entered() hs.alert.show('Resize Mode', { textSize = 20, radius = 10 }, 999999) end
|
|
|
|
function resize_mode:exited() hs.alert.closeAll() end
|
|
|
|
-- Enter resize mode
|
|
|
|
keymap.super {
|
|
key = 'r',
|
|
message = 'Enter resize mode',
|
|
fn = function() resize_mode:enter() end,
|
|
}
|
|
|
|
-- Exit resize mode (escape or return)
|
|
resize_mode:bind({}, 'escape', function() resize_mode:exit() end)
|
|
|
|
resize_mode:bind({}, 'return', function() resize_mode:exit() end)
|
|
|
|
-- Resize bindings (no modifiers needed in resize mode)
|
|
resize_mode:bind({}, 'h', function() os.execute(yabai_cmd .. ' -m window --resize left:-20:0 || ' .. yabai_cmd .. ' -m window --resize right:-20:0') end)
|
|
|
|
resize_mode:bind({}, 'j', function() os.execute(yabai_cmd .. ' -m window --resize bottom:0:20 || ' .. yabai_cmd .. ' -m window --resize top:0:20') end)
|
|
|
|
resize_mode:bind({}, 'k', function() os.execute(yabai_cmd .. ' -m window --resize top:0:-20 || ' .. yabai_cmd .. ' -m window --resize bottom:0:-20') end)
|
|
|
|
resize_mode:bind({}, 'l', function() os.execute(yabai_cmd .. ' -m window --resize right:20:0 || ' .. yabai_cmd .. ' -m window --resize left:20:0') end)
|
|
|
|
-- Shift variants for larger increments
|
|
resize_mode:bind(
|
|
{ 'shift' },
|
|
'h',
|
|
function() os.execute(yabai_cmd .. ' -m window --resize left:-50:0 || ' .. yabai_cmd .. ' -m window --resize right:-50:0') end
|
|
)
|
|
|
|
resize_mode:bind({ 'shift' }, 'j', function() os.execute(yabai_cmd .. ' -m window --resize bottom:0:50 || ' .. yabai_cmd .. ' -m window --resize top:0:50') end)
|
|
|
|
resize_mode:bind(
|
|
{ 'shift' },
|
|
'k',
|
|
function() os.execute(yabai_cmd .. ' -m window --resize top:0:-50 || ' .. yabai_cmd .. ' -m window --resize bottom:0:-50') end
|
|
)
|
|
|
|
resize_mode:bind({ 'shift' }, 'l', function() os.execute(yabai_cmd .. ' -m window --resize right:50:0 || ' .. yabai_cmd .. ' -m window --resize left:50:0') end)
|
|
|
|
-- Equalize windows
|
|
resize_mode:bind({}, 'e', function()
|
|
os.execute(yabai_cmd .. ' -m space --balance')
|
|
resize_mode:exit()
|
|
end)
|
|
|
|
-- Toggle notes scratchpad
|
|
keymap.super {
|
|
key = 'n',
|
|
message = 'Toggle notes scratchpad',
|
|
fn = function()
|
|
local result = yabai_query('--windows', '\'.[] | select(.scratchpad == "notes") | .id\'')
|
|
|
|
if result == '' then
|
|
local notes_dir = os.getenv 'HOME' .. '/NPersonal'
|
|
os.execute('/etc/profiles/per-user/rayandrew/bin/kitty --title notes --directory ' .. notes_dir .. ' &')
|
|
hs.timer.usleep(200000)
|
|
end
|
|
|
|
-- Toggle the scratchpad
|
|
os.execute(yabai_cmd .. ' -m window --toggle notes')
|
|
end,
|
|
}
|
|
|
|
keymap.super {
|
|
key = 't',
|
|
message = 'Toggle terminal scratchpad',
|
|
fn = function()
|
|
local result = yabai_query('--windows', '\'.[] | select(.scratchpad == "term") | .id\'')
|
|
|
|
if result == '' then
|
|
local home_dir = os.getenv 'HOME'
|
|
os.execute('/etc/profiles/per-user/rayandrew/bin/kitty --title floaterm --directory ' .. home_dir .. ' &')
|
|
hs.timer.usleep(200000)
|
|
end
|
|
|
|
-- Toggle the scratchpad
|
|
os.execute(yabai_cmd .. ' -m window --toggle term')
|
|
end,
|
|
}
|
|
|
|
-- keymap.super {
|
|
-- key = 'e',
|
|
-- message = 'Toggle explorer scratchpad',
|
|
-- fn = function()
|
|
-- local result = yabai_query('--windows', '\'.[] | select(.scratchpad == "explorer") | .id\'')
|
|
--
|
|
-- if result == '' then
|
|
-- local home_dir = os.getenv('HOME')
|
|
-- os.execute('/etc/profiles/per-user/rayandrew/bin/kitty -o close_on_child_death=yes --title explorer --directory ' .. home_dir .. ' -e yazi &')
|
|
-- hs.timer.usleep(200000)
|
|
-- end
|
|
--
|
|
-- -- Toggle the scratchpad
|
|
-- os.execute(yabai_cmd .. ' -m window --toggle explorer')
|
|
-- end,
|
|
-- }
|