Skip to content

Commit

Permalink
wezterm split modules
Browse files Browse the repository at this point in the history
  • Loading branch information
dotrakoun-clearstreet committed Dec 20, 2024
1 parent 647b60d commit 939b120
Show file tree
Hide file tree
Showing 4 changed files with 301 additions and 282 deletions.
82 changes: 82 additions & 0 deletions wezterm/dko/mappings.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
local wezterm = require("wezterm")
local panes = require("dko/panes")
local theme = require("dko/theme")

--- Key bindings

local k = setmetatable({}, { __index = table })

-- Disable some default keys
-- Use cli:
-- wezterm show-keys --lua
-- to see current mappings
local defaults_to_disable = {
{ key = "Enter", mods = "ALT" }, -- ToggleFullScreen bleh native fullscreen
{ key = "Tab", mods = "CTRL" }, -- ActivateTabRelative
{ key = "Tab", mods = "SHIFT|CTRL" }, -- ActivateTabRelative
{ key = '"', mods = "ALT|CTRL" }, -- SplitVertical
{ key = '"', mods = "CTRL|SHIFT|ALT" }, -- SplitVertical
{ key = "'", mods = "CTRL|SHIFT|ALT" }, -- SplitVertical
{ key = "%", mods = "ALT|CTRL" }, -- SplitHorizontal
{ key = "%", mods = "CTRL|SHIFT|ALT" }, -- SplitHorizontal
{ key = "5", mods = "CTRL|SHIFT|ALT" }, -- SplitHorizontal
{ key = "K", mods = "CTRL" }, -- ClearScrollback
{ key = "L", mods = "CTRL" }, -- ShowDebugOverlay
{ key = "M", mods = "CTRL" }, -- Hide
{ key = "M", mods = "SHIFT|CTRL" }, -- Hide
{ key = "N", mods = "CTRL" }, -- SpawnWindow
{ key = "R", mods = "CTRL" }, -- ReloadConfiguration
{ key = "R", mods = "SHIFT|CTRL" }, -- ReloadConfiguration
{ key = "T", mods = "CTRL" }, -- SpawnTab
{ key = "U", mods = "CTRL" }, -- CharSelect
{ key = "X", mods = "CTRL" }, -- ActivateCopyMode
{ key = "^", mods = "CTRL" }, -- ActivateTab
{ key = "Z", mods = "CTRL" }, -- TogglePaneZoomState
}
for _, cfg in pairs(defaults_to_disable) do
cfg.action = wezterm.action.DisableDefaultAssignment
k:insert(cfg)
end

-- Add my keys, modeled after konsole
k:insert({
key = "w",
mods = "CMD",
action = wezterm.action.CloseCurrentPane({ confirm = true }),
})
k:insert({
key = "t",
mods = "CTRL|SHIFT",
action = wezterm.action_callback(theme.toggle),
})
-- Pick pane, swap with active
k:insert({
key = "8",
mods = "CTRL|SHIFT",
action = wezterm.action.PaneSelect({ mode = "SwapWithActive" }),
})

-- Yes both number and ( ) bindings are needed, one for wezterm-git on arch
-- and one on wezterm stable from brew on mac
k:insert({
key = "9",
mods = "CTRL|SHIFT",
action = wezterm.action_callback(panes.split_horz),
})
k:insert({
key = "0",
mods = "CTRL|SHIFT",
action = wezterm.action_callback(panes.split_vert),
})
k:insert({
key = "(",
mods = "CTRL|SHIFT",
action = wezterm.action_callback(panes.split_horz),
})
k:insert({
key = ")",
mods = "CTRL|SHIFT",
action = wezterm.action_callback(panes.split_vert),
})

return k
138 changes: 138 additions & 0 deletions wezterm/dko/panes.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
local wezterm = require("wezterm")

local M = {}

-- Change split behavior
-- If this is a middle split, default behavior
-- - you can use this to do regular half splits by jumping into prev window
-- and split from there
-- If there is no split in that direction split is halved
-- If there's an existing split in that direction then
-- split prev,curr,new evenly into thirds
--
---@param dir "Left"|"Up"
local scaled_split = function(dir)
return function(win, pane)
--wezterm.log_info("split " .. dir)
local tab = win:active_tab()

local opposite = dir == "Left" and "Right" or "Down"
local next = tab:get_pane_direction(opposite)
if not next then
local size_key = dir == "Left" and "cols" or "viewport_rows"
local prev = tab:get_pane_direction(dir)
if prev then
-- first resize the prev pane to be 1/3 vs 2/6
-- then split this pane
local prev_width = prev:get_dimensions()[size_key]
local self_width = pane:get_dimensions()[size_key]
local total_width = prev_width + self_width
local onethird = math.floor(total_width / 3)

-- if 1/3 is 26cols, and prev is 30 cols, we want to
-- - grow pane by 4, i.e. shrink prev by 4
local difference = prev_width < onethird and 0 or prev_width - onethird
--wezterm.log_info(string.format('%s %s %s', onethird, prev_width, self_width))
win:perform_action(
wezterm.action.AdjustPaneSize({ dir, difference }),
pane
)
end
end

pane:split({ direction = dir == "Left" and "Right" or "Bottom" })
end
end

--- Get panes that are on the same axis as the tab's active pane
---@param axis 'y'|'x'
---@param tab table
---@return table siblings
local function get_axis_siblings(axis, tab)
local initial = tab:active_pane()
local siblings = { initial }
local prev_dir = axis == "x" and "Left" or "Up"
local next_dir = axis == "x" and "Right" or "Down"

local prev = tab:get_pane_direction(prev_dir)
while prev do
table.insert(siblings, 1, prev)
prev:activate()
prev = tab:get_pane_direction(prev_dir)
end

initial:activate() -- annoying
local next = tab:get_pane_direction(next_dir)
while next do
table.insert(siblings, next)
next:activate()
next = tab:get_pane_direction(next_dir)
end

initial:activate() -- restore
return siblings
end

--- Attempt to resize axis siblings to all the same size
---@param axis 'y'|'x'
M.balance = function(axis)
---@param win table
return function(win)
local tab = win:active_tab()
local initial = tab:active_pane()
local prev_dir = axis == "x" and "Left" or "Up"
local next_dir = axis == "x" and "Right" or "Down"
local siblings = get_axis_siblings(axis, tab)
local tab_size = tab:get_size()[axis == "x" and "cols" or "rows"]
local balanced_size = math.floor(tab_size / #siblings)
local pane_size_key = axis == "x" and "cols" or "viewport_rows"
wezterm.log_info(
string.format(
"resizing %s panes on %s axis to %s cells",
#siblings,
axis,
balanced_size
)
)

for i, p in ipairs(siblings) do
local pane_size = p:get_dimensions()[pane_size_key]
local adj_amount = pane_size - balanced_size
local adj_dir = adj_amount < 0 and next_dir or prev_dir
adj_amount = math.abs(adj_amount)
wezterm.log_info(
string.format(
"adjusting pane %s from %s by %s cells %s",
tostring(i),
tostring(pane_size),
tostring(adj_amount),
adj_dir
)
)

-- This does not work if you spawn a new term
-- os.execute(
-- string.format(
-- "wezterm cli adjust-pane-size --pane-id %s --amount %s %s",
-- tostring(p:pane_id()),
-- tostring(adj_amount),
-- adj_dir
-- )
-- )
p:activate()
win:perform_action(
-- AdjustPaneSize only acts on active pane
wezterm.action.AdjustPaneSize({ adj_dir, adj_amount }),
p -- this does not affect anything
)
end

-- restore initial since we had to activate each pane to resize it
initial:activate()
end
end

M.split_horz = scaled_split("Left")
M.split_vert = scaled_split("Up")

return M
76 changes: 76 additions & 0 deletions wezterm/dko/theme.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
local wezterm = require("wezterm")

--- Theme

local xdg_state_home = os.getenv("XDG_STATE_HOME")
or os.getenv("HOME") .. "/.local/state"
local colorscheme_file = ("%s/wezterm-colorscheme.txt"):format(xdg_state_home)

local notifier = "osascript -e 'display notification"
local close = "'"
if string.find(wezterm.target_triple, "linux") then
notifier = "notify-send --app-name=WezTerm --urgency=low --expire-time=500"
close = ""
end

---@param next_mode string
local sync_colorscheme = function(next_mode)
local file_handle = io.open(colorscheme_file, "w")
if file_handle then
os.execute(
('%s "updated %s with %s"%s'):format(
notifier,
colorscheme_file,
next_mode,
close
)
)
file_handle:write(next_mode)
file_handle:close()
else
os.execute(
('%s "could not update %s with %s"%s'):format(
notifier,
colorscheme_file,
next_mode,
close
)
)
end
end

local colorschemes = {
dark = "Twilight (base16)",
light = "Solarized (light) (terminal.sexy)",
}

local M = {}

---Sync the config with contents of the colorscheme_file
M.read = function()
local file_handle = io.open(colorscheme_file, "r")
if file_handle then
local key = file_handle:read()
file_handle:close()
if key and colorschemes[key] then
return colorschemes[key]
end
end

-- fallback
return colorschemes.dark
end

---@param win table
M.toggle = function(win)
local ecfg = win:effective_config()
local next_mode = ecfg.color_scheme == colorschemes.light and "dark"
or "light"
local overrides = win:get_config_overrides() or {}
local next_colorscheme = colorschemes[next_mode]
overrides.color_scheme = next_colorscheme
win:set_config_overrides(overrides)
sync_colorscheme(next_mode)
end

return M
Loading

0 comments on commit 939b120

Please sign in to comment.