跳过正文
  1. 文章/

个人zsh配置

··912 字·5 分钟
Code Zsh Shell
目录
开发环境配置 - 系列文章
§ : 本文

0. 写在开头
#

由于系统、环境等差异可能过大,这里只是记录个人的zsh配置,仅供参考。

0.1 .zshrc
#

# My zsh settings with zinit

# ------------------- 核心配置 -------------------
# 性能优化选项
skip_global_compinit=1
DISABLE_MAGIC_FUNCTIONS=true
ZSH_DISABLE_COMPFIX=true

# 补全系统设置
COMPLETION_WAITING_DOTS="true"
ZSH_AUTOSUGGEST_MANUAL_REBIND=1
ZSH_AUTOSUGGEST_USE_ASYNC=1
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=20

# ------------------- Powerlevel10k 即时提示 -------------------
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

# ------------------- zinit 插件管理器 -------------------
source "/usr/share/zinit/zinit.zsh"
autoload -Uz _zinit
(( ${+_comps} )) && _comps[zinit]=_zinit

# zinit annexes
zinit ice wait"1" lucid as"null" for \
    zdharma-continuum/zinit-annex-as-monitor \
    zdharma-continuum/zinit-annex-bin-gem-node \
    zdharma-continuum/zinit-annex-patch-dl \
    zdharma-continuum/zinit-annex-rust

# ------------------- 主题 -------------------
zinit ice depth=1
zinit light romkatv/powerlevel10k

# ------------------- 核心插件 -------------------
# fzf
zinit ice from"gh-r" as"command"
zinit light junegunn/fzf

# 补全增强 & 补全初始化
zinit ice wait"0a" lucid atload"zicompinit; zicdreplay" blockf
zinit light zsh-users/zsh-completions

# fzf-tab
zinit ice wait"0b" lucid
zinit light Aloxaf/fzf-tab

# 自动建议
zinit ice wait"0c" lucid \
    atload'
        _zsh_autosuggest_start
        bindkey "\`" autosuggest-accept
    '
zinit light zsh-users/zsh-autosuggestions

# 历史命令
zinit ice wait"0d" lucid from"gh-r" as"program" pick"*/atuin" \
    atload'
        eval "$(atuin init zsh)"
        bindkey "^R" _atuin_search_widget
    '
zinit light atuinsh/atuin

# 语法高亮
zinit ice wait"0e" lucid atinit"zpcompinit;zpcdreplay"
zinit light zdharma-continuum/fast-syntax-highlighting

# ------------------- CLI 工具 -------------------
# 核心工具(无延迟加载)
zinit ice wait"0" lucid from"gh-r" as"program" pick"eza*/eza"
zinit light eza-community/eza

zinit ice wait"0" lucid from"gh-r" as"program" pick"bat*/bat"
zinit light sharkdp/bat

# 延迟加载工具
zinit ice wait"1" lucid from"gh-r" as"program" pick"ripgrep*/rg"
zinit light BurntSushi/ripgrep

zinit ice wait"1" lucid from"gh-r" as"program" pick"fd*/fd"
zinit light sharkdp/fd

zinit ice wait"1" lucid from"gh-r" as"program" pick"lazydocker"
zinit light jesseduffield/lazydocker

zinit ice wait"1" lucid from"gh-r" as"program" pick"*/usr/bin/fastfetch"
zinit light fastfetch-cli/fastfetch

zinit ice wait"1" lucid from"gh-r" as"program" pick"duf"
zinit light muesli/duf

zinit ice wait"1" lucid as"program" pick"prettyping"
zinit load denilsonsa/prettyping

# bat-extras
zinit ice wait"1" lucid as"program" pick"src/batgrep.sh" \
    atload"alias batgrep='batgrep.sh'"
zinit ice wait"1" lucid as"program" pick"src/batdiff.sh" \
    atload"alias batdiff='batdiff.sh'"
zinit light eth-p/bat-extras


# ------------------- 补全配置 -------------------
# 基础补全设置
zstyle ':completion:*' completer _expand _complete _ignored
zstyle ':completion:*' matcher-list 'm:{a-z}={A-Z}'
zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
zstyle ':completion:*' menu no

# fzf-tab 基础设置
zstyle ':fzf-tab:*' use-fzf-default-opts yes

# fzf-tab 预览设置
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza --icons -1 --color=always $realpath'
zstyle ':fzf-tab:complete:cd:*' popup-pad 30 0
zstyle ':fzf-tab:complete:__zoxide_z:*' fzf-preview 'eza --icons -1 --color=always $realpath'
zstyle ':fzf-tab:complete:z:*' fzf-preview 'eza --icons -1 --color=always $realpath'

# 进程补全预览
zstyle ':fzf-tab:complete:kill:argument-rest' fzf-preview 'ps --pid=$word -o cmd --no-headers -w -w'
zstyle ':fzf-tab:complete:kill:argument-rest' fzf-flags '--preview-window=down:3:wrap'
zstyle ':fzf-tab:complete:kill:*' popup-pad 0 3

# fzf-tab 快捷键
zstyle ':fzf-tab:*' fzf-bindings '`:accept'
zstyle ':fzf-tab:*' switch-group '<' '>'

# ------------------- 自动建议配置 -------------------
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_COMPLETION_IGNORE='( |man |pikaur -S )*'
ZSH_AUTOSUGGEST_HISTORY_IGNORE='?(#c50,)'

# ------------------- fzf 配置 -------------------
export FZF_DEFAULT_OPTS="
--ansi
--layout=reverse
--info=inline
--height=50%
--multi
--cycle
--preview-window=right:50%
--preview-window=cycle
--prompt='λ -> '
--pointer='▷'
--marker='✓'
--color=bg+:236,gutter:-1,fg:-1,bg:-1,hl:-1,hl+:-1,prompt:-1,pointer:105,marker:-1,spinner:-1
"
export FZF_DEFAULT_COMMAND='fd --type f --hidden --follow --exclude .git'

# ------------------- Conda 配置 -------------------
export CONDA_AUTO_ACTIVATE_BASE=false
conda() {
    unfunction conda
    eval "$(/opt/miniforge/bin/conda shell.zsh hook)"
    conda $@
}
[[ "${CONDA_AUTO_ACTIVATE_BASE:-true}" == "true" ]] && {
    eval "$(/opt/miniforge/bin/conda shell.zsh hook)"
    conda activate base
}

# ------------------- 其他工具配置 -------------------
# zoxide
eval "$(zoxide init zsh --cmd cd)"

# 加载自定义别名
source $HOME/.zsh_aliases

# Powerlevel10k 配置
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh

0.2 .zsh_aliases
#


alias l="eza --icons --long --header"
alias ls="eza --icons --grid"
alias ll="eza --icons --long --header"
alias la="eza --icons --long --header --all"
alias lg="eza --icons --long --header --all --git"
alias tree="eza --icons --tree -L1"
alias cat="bat"
alias man="tldr"
alias mkdir='mkdir -p'
alias df="duf -style unicode -hide-mp '/run/credentials/*'"
alias top="bpytop"
alias gedit="gnome-text-editor"
alias nvidia-smi="watch -n 3 -c nvidia-smi"
alias x="unar"
alias ff="fastfetch" # 快速显示fastfetch
function tmp() {
    cd "$(mktemp -d /tmp/temp_XXX)" #创建临时目录
}

1. 基本信息
#

  • System: Arch Linux x86_64
  • Terminal: kitty
  • Shell: zsh
  • Theme: powerlevel10k
  • Plugins Manerger: zinit

2. 原有配置痛点
#

  1. 如果历史命令中有中文,按 up键,会出现历史命令错位和终止终端的问题。
  2. 有些时候,命令输入延迟很高,已经输入完一段命令,但是终端是慢慢一个字一个字跳的。
  3. 性能还是不够高。

3. 方案对比和选择
#

3.1 插件管理器或插件框架
#

序号项目说明优势劣势
1Oh My Zsh最流行的Zsh框架- 300+预置插件和150+主题
- 配置简单直观
- 社区庞大
- 启动速度慢
- 插件数量增加会显著降低性能
2Zinit现代化插件管理器- Turbo模式启动速度提升50-80%
- 支持选择性禁用/启用功能
- 完整兼容OMZ和Prezto插件
- 语法相对复杂
- 不适合新手
3Zim轻量级框架- 启动速度快
- 模块化设计
- 合理的默认配置
- 完整支持OMZ插件
- 内置功能相对较少
4Sheldon可配置的插件管理器- 配置灵活
- 支持延迟加载
- 支持多种shell
- 社区相对较小
5zsh4humans优化的Zsh环境- 启动速度快
- 默认配置合理
- 性能优化出色
- 定制性相对较低
6Antigen传统插件管理器- 类似包管理器的使用方式
- 自动更新插件
- 维护不够活跃
- 性能一般
7zgen轻量级管理器- 生成静态加载文件
- 启动相对较快
- 功能相对简单
- 更新较少
8zplug全功能插件管理器- 功能丰富
- 并行安装插件
- 已基本停止维护
- 性能一般

在这个里面,根据轻量化、性能好、社区维护活跃等因素,我最终选择了 Zinit作为插件管理器。

3.2 插件
#

  1. 语法高亮:fast-syntax-highlighting
  2. 命令补全:zsh-completionsfzf-tab
  3. 智能建议:zsh-autosuggestions
  4. 目录跳转:zoxide
    序号项目说明优势劣势
    1zoxideRust编写的现代化目录跳转工具- 性能最快,启动速度快
    - 使用简单直观
    - 支持所有主流shell
    - 需要额外安装
    - 不支持相对路径跳转
    2autojumpPython编写的经典跳转工具- 功能丰富完整
    - 高级特性多
    - 学习曲线较陡
    - 性能相对较慢
    3zZsh内置的目录跳转插件- 无需额外安装
    - 与Zsh深度集成
    - 功能相对基础
    - 仅支持Zsh
    4z.luaLua实现的跳转工具- 跨平台支持好
    - 配置灵活
    - 性能比zoxide慢
    - 需要Lua环境
    5zsh-zZsh专用的z实现- 轻量级
    - 安装简单
    - 仅支持Zsh
    - 功能较少
    6ZLOcationShell原生实现的跳转工具- 无外部依赖
    - 性能稳定
    - 功能相对简单
    - 社区较小
  5. 历史命令:atuin
    序号项目说明优势劣势
    1atuin基于SQLite的现代化shell历史记录工具- 支持多设备同步
    - 支持端到端加密
    - 可按目录/主机等过滤搜索
    - 记录命令执行时间和退出码
    - 支持自托管同步服务器
    - 配置简单,安装便捷
    - 首次打开仪表板较慢
    - 在mosh下可能出现屏幕显示问题
    - 同步机制不够直观
    - 配置无法跨设备同步
    2zsh-histdb基于SQLite的Zsh历史记录插件- 记录命令工作目录
    - 记录命令执行主机
    - 支持多数据库合并
    - 与zsh-autosuggestions集成良好
    - 支持按目录搜索历史
    - 不使用传统文本文件存储
    - 项目维护不够活跃
    - 仅支持Zsh
    - 配置相对复杂
  6. 主题美化:powerlevel10k

3.2 第三方命令行工具管理
#

由于改配置会同步 Docker深度学习环境远程服务器使用,系统包管理器不同(有ubuntuarchlinuxdebian等),故第三方命令行工具使用 zinit管理,而非使用包管理器管理。 则新建一系统时安装zshzinit,再同步配置即可,其余的交给zinit管理。

TODO: 之后用chezimo管理配置文件并同步到各个系统。

4. 测试工具
#

这里我们使用zsh-bench基准工具来测试zsh交互性能,再进行对比。

  • 测量指标
    1. first_prompt_lag_ms (首次提示符延迟) 打开新终端时,显示第一个命令提示符(如user@host:~$)所需的时间
      • 良好: < 50ms,几乎瞬间显示提示符
      • 较差: > 100ms,打开终端后明显等待才看到提示符
    2. first_command_lag_ms (首次命令延迟) 输入第一个命令(如ls)到执行完成的时间
      • 良好: < 200ms,输入命令后立即执行
      • 较差: > 500ms,输入第一个命令后明显卡顿
    3. command_lag_ms (命令延迟) 执行后续命令的平均响应时间
      • 良好: < 10ms,命令执行无感知延迟
      • 较差: > 50ms,每次执行命令都能感觉到轻微卡顿
    4. input_lag_ms (输入延迟) 按键到字符显示在屏幕上的时间
      • 良好: < 30ms,打字流畅自然
      • 较差: > 50ms,打字时感觉明显延迟或卡顿
    5. exit_time_ms (退出时间) 输入exit或按Ctrl+D到终端完全关闭的时间
      • 良好: < 100ms,终端立即关闭
      • 较差: > 200ms,关闭终端时出现明显延迟
  • 测试命令如下:
    ./zsh-bench -i 30 -l yes -g yes
    

5. 测试结果
#

==> benchmarking login shell of user xiadengma ...
creates_tty=0
has_compsys=0
has_syntax_highlighting=0
has_autosuggestions=0
has_git_prompt=1
first_prompt_lag_ms=18.829
first_command_lag_ms=78.340
command_lag_ms=4.930
input_lag_ms=3.903
exit_time_ms=45.429

可以看到当前zsh配置在性能上表现良好,响应速度快。

参考资料
#

xiadengma
作者
xiadengma
开发环境配置 - 系列文章
§ : 本文