现代终端工作流配置方案
目标
这套配置面向 infra / platform engineer 的日常工作流:
- Terminal: Ghostty
- Shell: zsh
- Prompt: starship
- Multiplexer: tmux
- CLI 美化: eza / bat / fd / ripgrep
- K8s: k9s / kubectx / kubens / stern / helm
- Git TUI: lazygit
- 辅助工具: fzf / zoxide / git-delta / jq / yq / bottom / dust
启动链路:
Ghostty -> zsh vi mode -> starship prompt -> tmux session -> lazygit / k9s / kubectl / eza / bat / rg / fd当前取舍:
- zsh 使用 vi mode。
- tmux prefix 使用
Ctrl-a。 - zsh insert mode 支持
Esc、Ctrl-[、jj进入 normal mode。 - Ghostty 显式把
Esc/Ctrl-[发送为 legacy ESC,避免 CSI-u1;5u影响 zsh vi mode。 - starship 初始化做幂等保护,避免反复
source ~/.zshrc后zle-keymap-selectwrapper 递归。
安装命令
brew install ghostty zsh starship tmux eza bat fd ripgrep k9s lazygit
brew install jq yq fzf zoxide git-delta kubectx helm stern bottom dust
brew install --cask font-jetbrains-mono-nerd-font配置文件位置
~/.zshrc
~/.config/starship.toml
~/.tmux.conf
~/.config/ghostty/config
~/.config/bat/configzsh 配置
文件:~/.zshrc
eval "$(/opt/homebrew/bin/brew shellenv)"
export PATH="/opt/homebrew/opt/openjdk@21/bin:$PATH"
export PATH="/Users/justinx/Library/Python/3.9/bin:$PATH"
export PATH="$HOME/bin:$PATH"
# >>> Codex modern CLI workflow >>>
export EDITOR="${EDITOR:-vim}"
export PAGER="${PAGER:-less}"
export LESS="-R"
if [[ -o interactive ]]; then
autoload -Uz compinit
compinit
bindkey -v
bindkey -M viins '^[' vi-cmd-mode
bindkey -M viins '\e' vi-cmd-mode
if [[ "${TERM:-}" != "dumb" ]]; then
if [[ "${widgets[zle-keymap-select]-}" == "user:starship_zle-keymap-select-wrapped" ]] && (( ${+functions[starship_zle-keymap-select]} )); then
zle -N zle-keymap-select starship_zle-keymap-select
elif [[ "${widgets[zle-keymap-select]-}" != user:starship_zle-keymap-select* ]]; then
eval "$(starship init zsh)"
fi
fi
if [[ "${TERM:-}" != "dumb" ]] && [[ -t 0 && -t 1 ]] && command -v fzf >/dev/null 2>&1; then
source <(fzf --zsh)
fi
fi
if command -v zoxide >/dev/null 2>&1; then
eval "$(zoxide init zsh)"
fi
if [[ -o interactive ]]; then
bindkey -M viins 'jj' vi-cmd-mode
export KEYTIMEOUT=20
for key in '^A' '^B' '^E' '^F' '^K' '^N' '^O' '^P' '^S' '^T' '^Y' '^Z'; do
if bindkey -M viins "$key" 2>/dev/null | command grep -q 'self-insert$'; then
bindkey -M viins "$key" undefined-key
fi
done
fi
alias ls="eza --icons --group-directories-first"
alias ll="eza -lah --icons --group-directories-first"
alias la="eza -a --icons --group-directories-first"
alias tree="eza --tree --icons"
alias cat="bat"
alias grep="rg"
alias find="fd"
alias lg="lazygit"
alias k="kubectl"
alias kctx="kubectl config current-context"
alias kx="kubectx"
alias kn="kubens"
alias ta="tmux attach -t"
alias tls="tmux ls"
alias tn="tmux new -s"
alias du="dust"
alias top="btm"
alias diff="delta"
# <<< Codex modern CLI workflow <<<说明:
bindkey -v明确启用 zsh vi mode。Esc/Ctrl-[绑定到vi-cmd-mode。jj也绑定到vi-cmd-mode。KEYTIMEOUT=20表示多键序列等待约 200ms;如果jj人工输入不稳定,可调到50或100。- 对仍是
self-insert的部分Ctrl+字母改成undefined-key,避免命令行出现^A、^E、^K这类控制字符。 - starship 初始化不再依赖
STARSHIP_SHELL环境变量判断,因为 tmux server 可能继承旧变量;改为检查当前 shell 的 zle widget。 - 反复
source ~/.zshrc时,如果 starship wrapper 已经递归套娃,会复位到starship_zle-keymap-select。
Starship 配置
文件:~/.config/starship.toml
format = """
$username$hostname$directory$git_branch$git_status$kubernetes$docker_context$terraform$nodejs$python$golang$java$cmd_duration
$character
"""
add_newline = true
[character]
success_symbol = "[❯](bold green)"
error_symbol = "[❯](bold red)"
[directory]
style = "bold cyan"
truncation_length = 3
truncate_to_repo = true
[git_branch]
symbol = "git:"
style = "bold purple"
[git_status]
style = "bold red"
[kubernetes]
disabled = false
symbol = "k8s:"
format = '[$symbol$context( \($namespace\))]($style) '
style = "bold blue"
[docker_context]
symbol = "docker:"
style = "blue"
[terraform]
symbol = "tf:"
style = "bold 105"
[nodejs]
symbol = "node:"
format = "[$symbol($version)]($style) "
[python]
symbol = "py:"
format = "[$symbol($version)]($style) "
[golang]
symbol = "go:"
format = "[$symbol($version)]($style) "
[java]
symbol = "java:"
format = "[$symbol($version)]($style) "
[cmd_duration]
min_time = 1000
format = "took [$duration](bold yellow) "tmux 配置
文件:~/.tmux.conf
set -g mouse on
setw -g mode-keys vi
set -sg escape-time 0
set -g history-limit 100000
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on
set -g default-terminal "tmux-256color"
set -ga terminal-overrides ",xterm-256color:Tc"
unbind C-b
set -g prefix C-a
bind C-a send-prefix
bind r source-file ~/.tmux.conf \; display-message "tmux config reloaded"
bind | split-window -h
bind - split-window -v
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
bind m resize-pane -Z
bind -n M-h previous-window
bind -n M-l next-window
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi y send-keys -X copy-selection-and-cancel
set -g status-bg black
set -g status-fg white
set -g status-left "#[fg=green]#S "
set -g status-right "#[fg=yellow]%Y-%m-%d %H:%M "说明:
- tmux prefix 使用
Ctrl-a。 Ctrl-a |左右分屏,Ctrl-a -上下分屏。Ctrl-a h/j/k/l在 pane 间移动。Ctrl-a Shift-h/j/k/l调整 pane 大小。Ctrl-a m最大化/恢复 pane。Alt-h/Alt-l切换 window。Ctrl-a r重新加载 tmux 配置。default-terminal使用tmux-256color,不使用较旧的screen-256color。
Ghostty 配置
文件:~/.config/ghostty/config
term = xterm-256color
font-family = JetBrainsMono Nerd Font
font-size = 14
theme = Catppuccin Mocha
window-padding-x = 10
window-padding-y = 8
cursor-style = block
cursor-style-blink = false
macos-option-as-alt = true
clipboard-read = allow
clipboard-write = allow
# Send a legacy ESC for zsh vi mode instead of CSI-u "1;5u".
keybind = escape=text:\x1b
keybind = ctrl+[=text:\x1b
keybind = ctrl+left_bracket=text:\x1b说明:
- Ghostty 默认/增强键盘协议下,
Ctrl+[可能发成 CSI-u1;5u。 - zsh vi mode 需要 legacy ESC,也就是
/bin/cat -v中看到的^[。 - 因此显式把
Esc、Ctrl+[、Ctrl+left_bracket映射成text:\x1b。 clipboard-read/write = allow允许终端和 tmux 更顺畅地使用系统剪贴板。
bat 配置
文件:~/.config/bat/config
--theme="TwoDark"
--style="numbers,changes,header"
--paging=auto验证命令
ghostty +validate-config --config-file=$HOME/.config/ghostty/config
starship explain >/tmp/starship-explain.txt && echo STARSHIP_OK
tmux -f ~/.tmux.conf start-server \; source-file ~/.tmux.conf \; show-options -g prefix
TERM=xterm-256color zsh -ic 'echo KEYTIMEOUT=$KEYTIMEOUT; bindkey -M viins jj; bindkey -M viins "^["'检查 Ghostty 是否发送 legacy ESC:
/bin/cat -v按 Esc 或 Ctrl+[,应该看到:
^[检查 starship wrapper 是否正常:
TERM=xterm-256color zsh -ic 'source ~/.zshrc; source ~/.zshrc; echo ${widgets[zle-keymap-select]-unset}'期望:
user:starship_zle-keymap-select主题切换
Ghostty 主题:
ghostty +list-themes修改:
theme = GitHub Dark Dimmed验证:
ghostty +validate-config --config-file=$HOME/.config/ghostty/configbat 主题:
bat --list-themes修改:
--theme="Catppuccin Mocha"注意事项
- tmux 内已有 pane 不会自动加载新的
.zshrc,需要执行source ~/.zshrc或新开 pane/window。 - tmux server 会继承启动时环境变量,例如
STARSHIP_SHELL、TERM,所以 starship 初始化判断不能只看环境变量。 - 如果
jj不稳定,优先调大KEYTIMEOUT。 - 如果命令行出现
^A、^E、^K等,说明某些 Ctrl 组合仍是self-insert,需要用bindkey -M viins检查。