Compare commits

..

3 commits

Author SHA1 Message Date
d6e648595a
refactor(zsh): use nixpkgs packages for zsh plugins
Replace manual GitHub fetchFromGitHub with packaged versions of zsh plugins and consolidate plugin loading through the plugins list instead of manual sourcing.
2025-10-04 10:25:53 +08:00
9971d2d2a5
feat(wezterm): add Alt+Delete to focus master pane
Implements spatial "master pane" focusing that mirrors XMonad's master
window concept. Alt+Delete now focuses the largest pane in the current
tab, completing the unified Delete key semantic across all tools:

- Gui+Delete (XMonad): Focus master window (largest in layout)
- Alt+Delete (WezTerm): Focus master pane (largest, ties to lowest index)
- Delete (Neovim): Center cursor view

The implementation is spatially-aware rather than content-aware,
maintaining the navigation layer's positional abstraction. When panes
are equal-sized, the lowest-indexed pane is chosen for predictability.
2025-10-03 23:53:20 +08:00
3fe607d310
refactor(wezterm): organize keybindings with key table namespaces
Implemented key tables to create clean, organized namespaces for tab and
pane management. This refactoring improves keybinding discoverability and
reduces cognitive load by grouping related operations.

Key changes:
- LEADER + t enters tab mode (n/q/r for new/quit/rename)
- LEADER + p enters pane mode (s/v/q/m for split/vsplit/quit/maximize)
- LEADER + Escape enters copy mode (vim-like pseudo-normal mode)
- CTRL + SHIFT + v for paste (standard terminal convention)
- Removed smart-splits plugin in favor of simpler native navigation
- Navigation keys remain at top level for quick access
2025-10-03 16:33:17 +08:00
2 changed files with 118 additions and 93 deletions

View file

@ -4,9 +4,6 @@ local wezterm = require("wezterm")
-- Log warnings or generate errors if we define an invalid configuration option
local config = wezterm.config_builder()
-- Install plugins
local smart_splits = wezterm.plugin.require("https://github.com/mrjones2014/smart-splits.nvim")
--
-- General configuration options.
--
@ -92,124 +89,103 @@ config.leader = { key = "a", mods = "ALT", timeout_milliseconds = 2000 }
-- General keymaps
config.keys = {
--
-- Tab management
-- Enter key table modes
--
{ -- Spawn new tab
{ -- Enter tab management mode
key = "t",
mods = "LEADER",
action = wezterm.action.SpawnTab("CurrentPaneDomain"),
action = wezterm.action.ActivateKeyTable({
name = "tab_mode",
one_shot = true,
}),
},
{ -- Enter pane management mode
key = "p",
mods = "LEADER",
action = wezterm.action.ActivateKeyTable({
name = "pane_mode",
one_shot = true,
}),
},
--
-- Navigation
--
{ -- Focus previous tab
key = "Home",
key = "LeftArrow",
mods = "ALT",
action = wezterm.action.ActivateTabRelative(-1),
},
{ -- Focus next tab
key = "End",
key = "RightArrow",
mods = "ALT",
action = wezterm.action.ActivateTabRelative(1),
},
{ -- Quit/close tab
key = "Q",
mods = "LEADER",
action = wezterm.action.CloseCurrentTab({ confirm = false }),
},
{ -- Rename current tab
key = ",",
mods = "LEADER",
action = wezterm.action_callback(function(window, pane)
local success, stdout, stderr = wezterm.run_child_process({
"dmenu",
"-fn",
"Fisa Code-10",
"-p",
"Tab name:",
})
if success and stdout then
local name = stdout:gsub("\n", "")
if name ~= "" then
window:active_tab():set_title(name)
end
end
end),
},
--
-- Pane management
--
{ -- Split pane vertically (bottom, 30%)
key = "s",
mods = "LEADER",
action = wezterm.action.SplitPane({
direction = "Down",
size = { Percent = 30 },
}),
},
{ -- Split pane horizontally (left, 28%)
key = "v",
mods = "LEADER",
action = wezterm.action.SplitPane({
direction = "Left",
size = { Percent = 28 },
}),
},
{ -- Focus previous pane
key = "PageUp",
key = "UpArrow",
mods = "ALT",
action = wezterm.action.ActivatePaneDirection("Prev"),
},
{ -- Focus next pane
key = "PageDown",
key = "DownArrow",
mods = "ALT",
action = wezterm.action.ActivatePaneDirection("Next"),
},
{ -- Rotate panes counter-clockwise
key = "PageUp",
mods = "ALT|CTRL",
mods = "ALT",
action = wezterm.action.RotatePanes("CounterClockwise"),
},
{ -- Rotate panes clockwise
key = "PageDown",
mods = "ALT|CTRL",
mods = "ALT",
action = wezterm.action.RotatePanes("Clockwise"),
},
{ -- Maximize/zoom pane
key = "m",
mods = "LEADER",
action = wezterm.action.TogglePaneZoomState,
},
{ -- Focus largest (master) pane
key = "Delete",
mods = "ALT",
action = wezterm.action_callback(function(window, pane)
local tab = window:active_tab()
local largest = nil
local largest_size = 0
{ -- Quit/close pane
key = "q",
mods = "LEADER",
action = wezterm.action.CloseCurrentPane({ confirm = false }),
for _, p in ipairs(tab:panes()) do
local dims = p:get_dimensions()
local size = dims.pixel_width * dims.pixel_height
if size > largest_size then
largest_size = size
largest = p
end
end
if largest and largest:pane_id() ~= pane:pane_id() then
largest:activate()
end
end),
},
--
-- Copy / Paste
--
{ -- Activate vi copy mode
key = "x",
{ -- Enter copy mode
key = "Escape",
mods = "LEADER",
action = wezterm.action.ActivateCopyMode,
},
{ -- Paste from clipboard
key = "p",
mods = "LEADER",
key = "v",
mods = "CTRL|SHIFT",
action = wezterm.action.PasteFrom("Clipboard"),
},
@ -224,6 +200,68 @@ config.keys = {
},
}
--
-- Key table definitions for modal keybinding namespaces
--
config.key_tables = {
-- Tab management mode (LEADER + t)
tab_mode = {
{ -- Create new tab
key = "n",
action = wezterm.action.SpawnTab("CurrentPaneDomain"),
},
{ -- Close current tab
key = "q",
action = wezterm.action.CloseCurrentTab({ confirm = false }),
},
{ -- Rename current tab
key = "r",
action = wezterm.action_callback(function(window, pane)
local success, stdout, stderr = wezterm.run_child_process({
"dmenu",
"-fn",
"Fisa Code-10",
"-p",
"Tab name:",
})
if success and stdout then
local name = stdout:gsub("\n", "")
if name ~= "" then
window:active_tab():set_title(name)
end
end
end),
},
},
-- Pane management mode (LEADER + p)
pane_mode = {
{ -- Split pane vertically (bottom, 30%)
key = "s",
action = wezterm.action.SplitPane({
direction = "Down",
size = { Percent = 30 },
}),
},
{ -- Split pane horizontally (left, 28%)
key = "v",
action = wezterm.action.SplitPane({
direction = "Left",
size = { Percent = 28 },
}),
},
{ -- Close current pane
key = "q",
action = wezterm.action.CloseCurrentPane({ confirm = false }),
},
{ -- Maximize/zoom pane
key = "m",
action = wezterm.action.TogglePaneZoomState,
},
},
}
-- Jump to specific tabs by number (ALT + 1-9)
for i = 1, 9 do
table.insert(config.keys, {
@ -233,16 +271,4 @@ for i = 1, 9 do
})
end
--
-- Enable neovim integration
--
smart_splits.apply_to_config(config, {
direction_keys = { "LeftArrow", "DownArrow", "UpArrow", "RightArrow" },
modifiers = {
move = "ALT",
resize = "ALT|CTRL",
},
})
return config

View file

@ -30,21 +30,20 @@
# Install plugins
plugins = [
{
{ # vi(vim) mode for ZSH
name = "zsh-vi-mode";
src = "${pkgs.zsh-vi-mode}/share/zsh-vi-mode";
}
{ # replace zsh's completion with fzf
name = "fzf-tab";
src = pkgs.fetchFromGitHub {
owner = "Aloxaf";
repo = "fzf-tab";
rev = "5a81e13792a1eed4a03d2083771ee6e5b616b9ab";
sha256 = "dPe5CLCAuuuLGRdRCt/nNruxMrP9f/oddRxERkgm1FE=";
};
src = "${pkgs.zsh-fzf-tab}/share/fzf-tab";
}
];
# Extra commands that should be added to '.zshrc'
initContent = ''
eval "$(direnv hook zsh)"
source ${pkgs.zsh-vi-mode}/share/zsh-vi-mode/zsh-vi-mode.plugin.zsh
bindkey "^[[1;5C" forward-word
bindkey "^[[1;5D" backward-word
export PATH