美化你的Terminal和Shell v2.0

3年前,我写过一篇文章,介绍了如何美化Windows Terminal和Shell(链接)。现在,我想系统性更新一下我在Terminal整个可视界面的整体美化方案。

终端模拟器(Terminal Emulator)

我选择了WezTerm作为我的终端模拟器。WezTerm是一个跨平台的终端模拟器,支持Windows、macOS和Linux。它具有高度可定制性和丰富的功能,非常适合喜欢个性化设置的用户。

使用Scoop安装WezTerm:

1
scoop install wezterm

WezTerm的配置文件是一个Lua脚本,位于%USERPROFILE%\.wezterm.lua。可以提出要求让AI帮你生成一个基础配置文件,然后根据个人喜好进行修改。例如我目前的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
local wezterm = require 'wezterm'
local config = wezterm.config_builder()

-- --------------------------------------------------------------------
-- Shell 选择
-- --------------------------------------------------------------------

-- 1. 环境判断
local is_windows = wezterm.target_triple:find("windows") ~= nil

-- 2. 设置默认启动 Shell (打开 WezTerm 直接进入 Nushell)
-- Windows 下通常是 "nu.exe",Linux 下是 "nu"
if is_windows then
config.default_prog = { "nu", "-l" }
else
config.default_prog = { "nu", "-l" }
end

-- 3. 定义启动菜单 (仅在你按下快捷键时显示)
local launch_menu = {}

if is_windows then
table.insert(launch_menu, { label = "Nushell", args = {"nu", "-l"} })
table.insert(launch_menu, { label = "Pwsh", args = {"pwsh.exe", "-NoLogo"} })
table.insert(launch_menu, { label = "CMD", args = {"cmd.exe"} })
table.insert(launch_menu, { label = "WSL: Fedora", args = {"wsl.exe", "-d", "fedora"} })
else
table.insert(launch_menu, { label = "Nushell", args = {"nu", "-l"} })
table.insert(launch_menu, { label = "Zsh", args = {"zsh", "-l"} })
table.insert(launch_menu, { label = "Bash", args = {"bash", "-l"} })
table.insert(launch_menu, { label = "Fish", args = {"fish", "-l"} })
end

-- 通用 SSH 项
table.insert(launch_menu, { label = "SSH: Server", args = {"ssh", "user@ip"} })

config.launch_menu = launch_menu

-- --------------------------------------------------------------------
-- 外观
-- --------------------------------------------------------------------

-- 日夜切换
-- 监听配置重载或系统主题切换
wezterm.on('window-config-reloaded', function(window, pane)
local overrides = window:get_config_overrides() or {}
local appearance = window:get_appearance()
local is_dark = appearance:find("Dark")

if is_dark then
overrides.colors = { background = '#000000' }
overrides.color_scheme = 'Catppuccin Mocha'
else
overrides.colors = { background = '#f8f8f8' }
overrides.color_scheme = 'Catppuccin Latte'
end
window:set_config_overrides(overrides)
end)

-- 透明度
config.window_background_opacity = 0.5

-- 初始状态:无标签栏,无按钮,无滚动条,仅保留调整大小边缘
config.enable_tab_bar = false
config.window_decorations = "RESIZE"
config.window_padding = { left = 15, right = 15, top = 15, bottom = 10 }
config.enable_scroll_bar = false
-- 光标样式:呼吸感
config.default_cursor_style = 'BlinkingBar'
-- 高帧率
config.max_fps = 165
-- 滚动缓冲区行数20000
config.scrollback_lines = 20000

-- --------------------------------------------------------------------
-- 字体
-- --------------------------------------------------------------------

config.font = wezterm.font_with_fallback({
{ family = 'JetBrainsMono Nerd Font', weight = 'Medium', harfbuzz_features = { 'calt', 'liga', 'clig' } },
{ family = 'FiraCode Nerd Font', weight = 'Medium' },
{ family = 'Microsoft YaHei', weight = 'Regular' },
{ family = 'Noto Sans SC', weight = 'Regular' },
})
config.font_size = 12.0

-- --------------------------------------------------------------------
-- 动态切换
-- --------------------------------------------------------------------
wezterm.on('toggle-all-controls', function(window, pane)
local overrides = window:get_config_overrides() or {}
if not overrides.enable_tab_bar then
-- 激活模式:显示标签栏 + 显示集成按钮
overrides.enable_tab_bar = true
overrides.window_decorations = "INTEGRATED_BUTTONS|RESIZE"
else
-- 隐藏模式:回到纯净状态
overrides.enable_tab_bar = false
overrides.window_decorations = "RESIZE"
end
window:set_config_overrides(overrides)
end)

-- 自动识别超链接
config.hyperlink_rules = wezterm.default_hyperlink_rules()

-- --------------------------------------------------------------------
-- 强制居中
-- --------------------------------------------------------------------
-- 1. 首先,在 config 声明下方设置初始尺寸(字符数)
config.initial_cols = 80
config.initial_rows = 20

-- 2. 使用 gui-startup 事件实现居中
wezterm.on('gui-startup', function(cmd)
local screen = wezterm.gui.screens().main
-- 这里的 10 和 20 是基于 JetBrains Mono 12pt 的大致像素估算
-- 宽度 = 120列 * 10像素 = 1200px
-- 高度 = 30行 * 20像素 = 600px
local width = 1200
local height = 600

local _, _, window = wezterm.mux.spawn_window(cmd or {})
local gui_window = window:gui_window()

-- 计算居中坐标
local x = (screen.width - width) / 2
local y = (screen.height - height) / 2

-- 强制设置位置
gui_window:set_position(x, y)
end)

-- --------------------------------------------------------------------
-- 快捷键
-- --------------------------------------------------------------------
-- 禁用所有默认快捷键,重新定义
config.disable_default_key_bindings = true
config.keys = {
-- 复制粘贴快捷键
{
key = 'C',
mods = 'CTRL',
action = wezterm.action_callback(function(window, pane)
local selection = window:get_selection_text_for_pane(pane)
if selection == "" then
window:perform_action(wezterm.action.SendKey{key='c', mods='CTRL'}, pane)
else
window:perform_action(wezterm.action.CopyTo 'Clipboard', pane)
end
end),
},
{ key = 'V', mods = 'CTRL|SHIFT', action = wezterm.action.PasteFrom 'Clipboard' },
-- 打开命令面板
{ key = 'P', mods = 'CTRL|SHIFT', action = wezterm.action.ActivateCommandPalette },
-- 绑定一键切换:标签栏、拖动、按钮同时出现/消失
{ key = 'B', mods = 'CTRL|SHIFT', action = wezterm.action.EmitEvent 'toggle-all-controls' },
-- 分屏快捷键
{ key = 's', mods = 'ALT', action = wezterm.action.SplitVertical { domain = 'CurrentPaneDomain' } },
{ key = 'v', mods = 'ALT', action = wezterm.action.SplitHorizontal { domain = 'CurrentPaneDomain' } },
-- 搜索快捷键
{ key = 'F', mods = 'CTRL|SHIFT', action = wezterm.action.Search { CaseInSensitiveString = "" } },
-- 按下 Alt + S (Switch) 呼出Shell选择菜单
{ key = 's', mods = 'ALT', action = wezterm.action.ShowLauncherArgs { flags = 'LAUNCH_MENU_ITEMS' } },
}

-- 自动重载配置文件
config.automatically_reload_config = true

return config
  • 字体:JetBrainsMono Nerd Font
  • 颜色方案:Catppuccin Latte/Mocha

Shell

我选择了Nushell作为我的主要Shell。Nushell是一个现代化的Shell,具有强大的数据处理能力和友好的用户界面。

输入code $nu.env-path打开启动变量,将VSCode设置为Nushell的默认编辑器,删除右侧提示符:

1
2
$env.EDITOR = "code"
$env.PROMPT_COMMAND_RIGHT = ""

使用config nu命令可以查看和修改Nushell的配置文件config.nu。将启动横幅关闭以保持界面简洁,启用颜色支持和关闭OSC133集成(WezTerm专有问题)以避免与终端冲突:

1
2
3
4
5
6
7
8
9
$env.config = {
show_banner: false
ls: {
use_ls_colors: true
}
shell_integration: {
osc133: false //Nushell会频繁发送终端位置标记,WezTerm可能过度响应这些标记,导致终端不断重绘显示区域
}
}
  • 命令提示符:Starship

Starship是一个跨Shell的命令提示符,可以与Nushell无缝集成。安装Starship后,编辑Nushell的配置文件config.nu,添加以下内容以启用Starship:

1
2
mkdir ($nu.data-dir | path join "vendor/autoload")
starship init nu | save -f ($nu.data-dir | path join "vendor/autoload/starship.nu")

对于PowerShell用户,可以运行code $PROFILE打开PowerShell配置文件,添加以下内容以启用Starship:

1
Invoke-Expression (&starship init powershell)