wezterm终端快捷键自定义绑定方案
为了寻求一种尽量简单并符合习惯的自定义快捷键方案, 于是就有了下面的配置.
完整配置
-- ~/.config/wezterm/wezterm.lua
local wezterm = require 'wezterm'
local config = wezterm.config_builder()
local act = wezterm.action
local mux = wezterm.mux
config.color_scheme = 'Tokyo Night'
config.font = wezterm.font_with_fallback {
'JetBrains Mono', -- Your primary font
'PingFang SC', -- macOS built-in Chinese font
'Noto Sans CJK SC', -- If installed
}
-- ============================================
-- custom key bindings
-- ============================================
config.keys = {
-- tab management
{ key = 't', mods = 'CMD', action = act.SpawnTab 'CurrentPaneDomain' },
{ key = 'w',
mods = 'CMD',
action = wezterm.action_callback(function(win, pane)
local tab = win:active_tab()
local panes = tab:panes()
if #panes > 1 then
win:perform_action(act.CloseCurrentPane{confirm=false}, pane)
else
win:perform_action(act.CloseCurrentTab{confirm=false}, pane)
end
end),},
{ key = '[', mods = 'CMD|SHIFT', action = act.ActivateTabRelative(-1) },
{ key = ']', mods = 'CMD|SHIFT', action = act.ActivateTabRelative(1) },
{ key = 'e', mods = 'CMD', action = act.ActivateLastTab },
-- pane division
{ key = 'd', mods = 'CMD', action = act.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = 'd', mods = 'CMD|SHIFT', action = act.SplitVertical { domain = 'CurrentPaneDomain' } },
-- vim navigation
{ key = 'h', mods = 'CMD', action = act.ActivatePaneDirection 'Left' },
{ key = 'j', mods = 'CMD', action = act.ActivatePaneDirection 'Down' },
{ key = 'k', mods = 'CMD', action = act.ActivatePaneDirection 'Up' },
{ key = 'l', mods = 'CMD', action = act.ActivatePaneDirection 'Right' },
-- pane resizing
{ key = 'LeftArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Left', 5 } },
{ key = 'RightArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Right', 5 } },
{ key = 'UpArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Up', 5 } },
{ key = 'DownArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Down', 5 } },
-- other common actions
{ key = 'Enter', mods = 'CMD', action = act.ToggleFullScreen },
{ key = '+', mods = 'CMD', action = act.IncreaseFontSize },
{ key = '-', mods = 'CMD', action = act.DecreaseFontSize },
{ key = '0', mods = 'CMD', action = act.ResetFontSize },
{ key = 'f', mods = 'CMD', action = act.Search 'CurrentSelectionOrEmptyString' },
{ key = 'p', mods = 'CMD', action = act.ActivateCommandPalette },
{ key = 'k', mods = 'CMD', action = act.ClearScrollback 'ScrollbackAndViewport' },
{ key = '[', mods = 'CMD', action = act.ActivateCopyMode },
}
-- enable CMD + number to switch to tabs 1-9
for i = 1, 9 do
table.insert(config.keys, { key = tostring(i), mods = 'CMD', action = act.ActivateTab(i-1) })
end
return config
自定义命令解释示例
cmd + w 优先关闭当前pane之后是tab最后是window
由于 WezTerm 中在只有一个tab 时, 按下 cmd+w 会直接关闭当前 pane, 从而导致整个窗口关闭. 也有人用cmd+shift+w关闭pane, cmd+w关闭tab区分, 但我不喜欢这样.
cmd + k 清空终端的所有内容——包括回滚历史和当前屏幕。
| 操作 | 清除屏幕 | 清除回滚历史 | 快捷键 |
|---|---|---|---|
| `clear` 命令 | ✅ | ❌(历史还在) | 无 |
| `Cmd+K` | ✅ | ✅(彻底清空) | `Cmd+K` |
| `Ctrl+L` | ✅ | ❌ | `Ctrl+L` |
cmd + [ 复制模式(Copy Mode)
什么是Copy Mode? 复制模式是一种键盘驱动的文本选择和导航模式,让你可以在终端缓冲区(包括回滚历史)中用键盘自由移动光标、选中文本并复制,无需使用鼠标。
在 Copy Mode 中你可以做什么? 进入复制模式后,屏幕右下角会显示 – COPY MODE – 提示,此时可以:
| 按键 | 功能 |
|---|---|
| `h/j/k/l` | 左/下/上/右移动光标(Vi 风格) |
| `b/w` | 按单词前后移动 |
| `0/$` | 跳到行首/行尾 |
| `gg/G` | 跳到缓冲区顶部/底部 |
| `Ctrl+u/d` | 向上/向下翻半页 |
| `v` | 开始字符选择(可视模式) |
| `V` | 开始行选择 |
| `y` | 复制选中文本到剪贴板 |
| `q` / `Esc` | 退出复制模式 |
使用场景
- 查看大量历史输出:日志、命令输出太长,用键盘快速定位和选择
- 纯键盘工作流:不想把手从键盘移到鼠标上
- 服务器环境:通过 SSH 连接时,无法使用鼠标选择
AI 生成参考版本
-- WezTerm macOS 专属配置
-- 保存路径: ~/.config/wezterm/wezterm.lua
local wezterm = require 'wezterm'
local config = {}
-- 使用新的配置构建器(兼容旧版本)
if wezterm.config_builder then
config = wezterm.config_builder()
end
local act = wezterm.action
-- 检测处理器架构
local is_arm = wezterm.target_triple:find('aarch64') ~= nil
-- ============================================
-- macOS 专属外观设置
-- ============================================
-- 配色方案
config.color_scheme = 'Tokyo Night'
-- 字体配置 - 兼容 Intel 和 Apple Silicon
config.font = wezterm.font_with_fallback {
'JetBrains Mono', -- 主字体(可替换为你喜欢的)
'PingFang SC', -- macOS 自带苹方字体
'Noto Sans CJK SC', -- 思源黑体(如果已安装)
}
config.font_size = is_arm and 14.0 or 13.5
config.line_height = 1.2
-- 启用连字
config.harfbuzz_features = { 'calt=1', 'clig=1', 'liga=1' }
-- macOS 原生窗口样式
config.window_decorations = "RESIZE"
config.native_macos_fullscreen_mode = true
-- 窗口透明度和毛玻璃效果
config.window_background_opacity = 0.92
config.macos_window_background_blur = is_arm and 30 or 20
-- 窗口边距
config.window_padding = {
left = 12,
right = 12,
top = 12,
bottom = 8,
}
-- 初始窗口大小
config.initial_cols = 140
config.initial_rows = 40
-- 标签页样式
config.enable_tab_bar = true
config.hide_tab_bar_if_only_one_tab = true
config.use_fancy_tab_bar = true
config.tab_max_width = 40
-- 标签页颜色
config.colors = {
tab_bar = {
background = 'rgba(0, 0, 0, 0)',
active_tab = {
bg_color = 'rgba(108, 112, 134, 0.3)',
fg_color = '#c0caf5',
},
inactive_tab = {
bg_color = 'rgba(68, 71, 90, 0.2)',
fg_color = '#787c99',
},
inactive_tab_hover = {
bg_color = 'rgba(88, 91, 112, 0.3)',
fg_color = '#a9b1d6',
},
},
}
-- ============================================
-- 性能优化
-- ============================================
config.front_end = "WebGpu"
config.webgpu_power_preference = is_arm and "HighPerformance" or "LowPower"
config.max_fps = is_arm and 120 or 60
config.animation_fps = is_arm and 120 or 60
-- 滚动设置
config.scrollback_lines = 10000
config.enable_scroll_bar = false
-- ============================================
-- macOS 专属快捷键
-- ============================================
config.keys = {
-- 标签页管理
{ key = 't', mods = 'CMD', action = act.SpawnTab 'CurrentPaneDomain' },
{ key = 'w', mods = 'CMD', action = act.CloseCurrentTab { confirm = false } },
{ key = '[', mods = 'CMD|SHIFT', action = act.ActivateTabRelative(-1) },
{ key = ']', mods = 'CMD|SHIFT', action = act.ActivateTabRelative(1) },
-- 窗格分割
{ key = 'd', mods = 'CMD', action = act.SplitHorizontal { domain = 'CurrentPaneDomain' } },
{ key = 'd', mods = 'CMD|SHIFT', action = act.SplitVertical { domain = 'CurrentPaneDomain' } },
{ key = 'w', mods = 'CMD', action = act.CloseCurrentPane { confirm = false } },
-- 窗格导航 (Vim 风格)
{ key = 'h', mods = 'CMD', action = act.ActivatePaneDirection 'Left' },
{ key = 'j', mods = 'CMD', action = act.ActivatePaneDirection 'Down' },
{ key = 'k', mods = 'CMD', action = act.ActivatePaneDirection 'Up' },
{ key = 'l', mods = 'CMD', action = act.ActivatePaneDirection 'Right' },
-- 窗格大小调整
{ key = 'LeftArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Left', 5 } },
{ key = 'RightArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Right', 5 } },
{ key = 'UpArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Up', 5 } },
{ key = 'DownArrow', mods = 'CMD|SHIFT', action = act.AdjustPaneSize { 'Down', 5 } },
-- 全屏和缩放
{ key = 'Enter', mods = 'CMD', action = act.ToggleFullScreen },
{ key = '+', mods = 'CMD', action = act.IncreaseFontSize },
{ key = '-', mods = 'CMD', action = act.DecreaseFontSize },
{ key = '0', mods = 'CMD', action = act.ResetFontSize },
-- 搜索和其他功能
{ key = 'f', mods = 'CMD', action = act.Search 'CurrentSelectionOrEmptyString' },
{ key = 'p', mods = 'CMD', action = act.ActivateCommandPalette },
{ key = '[', mods = 'CMD', action = act.ActivateCopyMode },
{ key = 'k', mods = 'CMD', action = act.ClearScrollback 'ScrollbackAndViewport' },
}
-- 快速切换标签页 Cmd+1 到 Cmd+9
for i = 1, 9 do
table.insert(config.keys, {
key = tostring(i),
mods = 'CMD',
action = act.ActivateTab(i - 1),
})
end
-- ============================================
-- 鼠标设置
-- ============================================
config.mouse_bindings = {
{ event = { Down = { streak = 1, button = 'Right' } }, mods = 'NONE', action = act.PasteFrom 'Clipboard' },
{ event = { Up = { streak = 1, button = 'Left' } }, mods = 'CMD', action = act.OpenLinkAtMouseCursor },
{ event = { Down = { streak = 1, button = 'Middle' } }, mods = 'NONE', action = act.Nop },
}
-- ============================================
-- Shell 和环境配置
-- ============================================
config.default_prog = { '/bin/zsh', '-l' }
-- Homebrew 路径设置
local homebrew_path = is_arm and '/opt/homebrew/bin' or '/usr/local/bin'
config.set_environment_variables = {
PATH = homebrew_path .. ':' .. os.getenv('PATH'),
}
-- ============================================
-- 其他设置
-- ============================================
config.automatically_reload_config = true
config.window_close_confirmation = 'NeverPrompt'
config.clean_exit_codes = { 130 }
-- URL 检测
config.hyperlink_rules = wezterm.default_hyperlink_rules()
table.insert(config.hyperlink_rules, {
regex = [[\b\w+://[\w.-]+\S*\b]],
format = '$0',
})
config.selection_word_boundary = ' \t\n{}[]()"\',;:`│'
-- macOS 快捷键
config.send_composed_key_when_left_alt_is_pressed = false
config.send_composed_key_when_right_alt_is_pressed = true
-- 视觉铃声
config.audible_bell = 'Disabled'
config.visual_bell = {
fade_in_function = 'EaseIn',
fade_in_duration_ms = 150,
fade_out_function = 'EaseOut',
fade_out_duration_ms = 150,
}
-- ============================================
-- 状态栏和标签栏自定义
-- ============================================
wezterm.on('update-right-status', function(window, pane)
local date = wezterm.strftime '%a %b %-d %H:%M '
local cwd_uri = pane:get_current_working_dir()
local cwd = ''
if cwd_uri then
cwd = cwd_uri.file_path
local home = wezterm.home_dir
cwd = cwd:gsub('^' .. home, '~')
local parts = {}
for part in cwd:gmatch('[^/]+') do
table.insert(parts, part)
end
if #parts > 2 then
cwd = '.../' .. parts[#parts - 1] .. '/' .. parts[#parts]
end
end
window:set_right_status(wezterm.format {
{ Foreground = { Color = '#7aa2f7' } },
{ Text = cwd .. ' ' },
{ Foreground = { Color = '#9ece6a' } },
{ Text = date },
})
end)
wezterm.on('format-tab-title', function(tab, tabs, panes, config, hover, max_width)
local title = tab.active_pane.title
local index = tab.tab_index + 1
if title:find('zsh') or title:find('bash') then
title = '~'
end
return {
{ Text = ' ' .. index .. ': ' .. title .. ' ' },
}
end)
return config
Comments:
Email questions, comments, and corrections to hi@smartisan.dev.
Submissions may appear publicly on this website, unless requested otherwise in your email.