跳转到主要内容

Zsh 一键复刻配置

· 约 4 分钟阅读

在一台全新的 macOS 机器上复刻我的 zsh 环境。

用法:把下面 §1 的整个代码块整块复制,粘贴给 Claude Code(或任意能跑 shell 的 AI 助手)即可。它是自包含的——所有约束、安装顺序、~/.zshrc 全文都在块内,不依赖任何本地文件、也不需要先 clone 仓库。§2 之后是给人看的参考,复刻时不必读。

适用环境:macOS (Apple Silicon),Homebrew 装在 /opt/homebrew,主目录 ~ = /Users/<you>。 配置快照时间:2026-05-20,基于 zsh + Oh My Zsh + Powerlevel10k。


1. 一键复刻 Prompt(唯一入口,整块复制)

你是我的环境配置助手。请在这台全新的 macOS (Apple Silicon) 机器上复刻一套 zsh 环境。
你需要的所有信息都在本提示词内——不要去读任何本地文件,也不要假设仓库已经 clone 下来。

【总约束】
- 动手前先备份:若 ~/.zshrc、~/.zshenv、~/.zprofile 已存在,各复制一份为 *.bak.<今天日期>,
  绝不直接覆盖未备份的文件。
- Homebrew 必须走 USTC 镜像(见下方 ~/.zshrc 里的 HOMEBREW_* 变量),否则国内首次拉取会卡死。
  安装 Homebrew 之前就要先 export 这些镜像变量。
- 全程只问我一次:要不要把我旧机器上的全部 brew 包(leaves + casks)也装回来。
  其余步骤请自主完成,不要逐步向我确认。
- 装完不要替我运行 `p10k configure`,留给我自己选样式。

【安装顺序】
1. Homebrew(先 export USTC 镜像变量,再跑官方安装脚本)
2. Oh My Zsh(unattended 模式)
3. Powerlevel10k 主题 + zsh-autosuggestions + zsh-syntax-highlighting
   (git clone 到 ~/.oh-my-zsh/custom 下对应目录)
4. Fira Code Nerd Font(brew cask,P10k 图标字体)
5. nvm → node(nvm install --lts,再 nvm alias default lts/*)
6. uv(astral 官方脚本)
7. bun(官方脚本)
8. pnpm、go(brew install)
9. miniforge(brew cask),装完运行 `conda init zsh`
   —— 这一步会自动往 ~/.zshrc 写入 conda 初始化块(含当前用户的绝对路径)
10. 把 ~/.zshrc / ~/.zshenv / ~/.zprofile 写成下面给定的内容

【~/.zshrc 的完整内容】
注意:下方标着 ">>> conda initialize >>>" 的那一段是占位说明,请勿照抄——
它由上一步的 `conda init zsh` 自动生成,会针对当前用户的 home 写入正确路径。其余内容请原样写入。

```bash
# =============================================================================
# Powerlevel10k Instant Prompt — MUST be at the top
# =============================================================================
# Lets the prompt appear immediately while the rest of zshrc loads in background.
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

# =============================================================================
# Oh My Zsh + Powerlevel10k
# =============================================================================
export ZSH="$HOME/.oh-my-zsh"
ZSH_THEME="powerlevel10k/powerlevel10k"

# Skip omz auto-update check on startup (run `omz update` manually when needed)
zstyle ':omz:update' mode disabled

# Skip compfix audit (we trust our completions; saves ~150 ms)
ZSH_DISABLE_COMPFIX=true

plugins=(
  git
  zsh-syntax-highlighting
  zsh-autosuggestions
)

source $ZSH/oh-my-zsh.sh

# Powerlevel10k user config (created by `p10k configure` wizard).
[[ -f ~/.p10k.zsh ]] && source ~/.p10k.zsh

# =============================================================================
# Terminal theme-report stripping (Ghostty / Kiro / cmux compatibility)
# =============================================================================
typeset -g _DTR_FIRST_DONE=
function _disable_terminal_theme_reports() {
  [[ -o interactive ]] || return 0
  # Skip the first precmd: it fires inside P10k's instant-prompt capture
  # window and the escape would trip the "console output" warning.
  if [[ -z $_DTR_FIRST_DONE ]]; then
    _DTR_FIRST_DONE=1
    return 0
  fi
  printf '\e[?2031l'
}

function _strip_terminal_theme_report_and_accept_line() {
  local compact="$BUFFER"
  compact=${compact// /}
  compact=${compact//$'\t'/}
  compact=${compact//$'\r'/}
  compact=${compact//$'\n'/}

  if [[ "$compact" =~ '^(\??997;[12]n)+$' ]]; then
    BUFFER=""
    CURSOR=0
    zle redisplay
    return 0
  fi

  zle .accept-line
}

autoload -Uz add-zsh-hook
if [[ -o interactive ]]; then
  add-zsh-hook precmd _disable_terminal_theme_reports
  zle -N accept-line _strip_terminal_theme_report_and_accept_line
fi

# =============================================================================
# Homebrew (China mirrors via USTC)
# =============================================================================
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.ustc.edu.cn/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.ustc.edu.cn/homebrew-core.git"
export HOMEBREW_API_DOMAIN="https://mirrors.ustc.edu.cn/api/homebrew/core"
export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.ustc.edu.cn/homebrew-bottles"
export HOMEBREW_AUTO_UPDATE_SECS=31536000

# =============================================================================
# Node via NVM — lazy-load
# =============================================================================
# Strategy: prepend the default node version's bin to PATH so node/npm/npx
# work instantly. Only when you actually call `nvm` itself does nvm.sh load
# (saves ~2000 ms of startup). 99% of users never call nvm directly.
export NVM_DIR="$HOME/.nvm"

# Resolve default version alias to a concrete version dir
__nvm_default_alias=$(<"$NVM_DIR/alias/default" 2>/dev/null)
if [ -n "$__nvm_default_alias" ]; then
  if [[ "$__nvm_default_alias" == v* ]]; then
    __nvm_default_version="$__nvm_default_alias"
  else
    __nvm_default_version=$(ls -1 "$NVM_DIR/versions/node" 2>/dev/null \
      | grep "^v${__nvm_default_alias}" | sort -V | tail -1)
  fi
  if [ -n "$__nvm_default_version" ] \
     && [ -d "$NVM_DIR/versions/node/$__nvm_default_version/bin" ]; then
    export PATH="$NVM_DIR/versions/node/$__nvm_default_version/bin:$PATH"
  fi
fi
unset __nvm_default_alias __nvm_default_version

# Lazy nvm: first call to `nvm` sources nvm.sh, then re-runs the call
nvm() {
  unset -f nvm
  [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
  [ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
  nvm "$@"
}

# =============================================================================
# Go
# =============================================================================
export GOPATH="$HOME/go"
export PATH="$PATH:$GOPATH/bin"

# =============================================================================
# uv (Python — replaces pip in muscle memory)
# =============================================================================
[ -s "$HOME/.local/bin/env" ] && . "$HOME/.local/bin/env"
alias pip='uv pip'
alias venv='uv venv'

# =============================================================================
# Bun
# =============================================================================
export BUN_INSTALL="$HOME/.bun"
export PATH="$BUN_INSTALL/bin:$PATH"
[ -s "$HOME/.bun/_bun" ] && source "$HOME/.bun/_bun"

# =============================================================================
# Antigravity
# =============================================================================
export PATH="$HOME/.antigravity/antigravity/bin:$PATH"

# =============================================================================
# pnpm
# =============================================================================
export PNPM_HOME="$HOME/Library/pnpm"
case ":$PATH:" in
  *":$PNPM_HOME:"*) ;;
  *) export PATH="$PNPM_HOME:$PATH" ;;
esac

# =============================================================================
# Kiro IDE shell integration (only when running inside Kiro)
# =============================================================================
[[ "$TERM_PROGRAM" == "kiro" ]] && . "$(kiro --locate-shell-integration-path zsh)"

# =============================================================================
# Miniforge / conda — Python ecosystem
# =============================================================================
export MINIFORGE_HOME="$HOME/miniforge3"
export MINIFORGE_PYTHON="$MINIFORGE_HOME/bin/python"
export PIPX_DEFAULT_PYTHON="$MINIFORGE_PYTHON"
export UV_PYTHON="$MINIFORGE_PYTHON"

# >>> conda initialize >>>
# 占位:不要照抄这一段。装完 miniforge 后运行 `conda init zsh`,
# conda 会在这里自动写入针对当前用户 home 的初始化代码
# (形如 __conda_setup="$('$HOME/miniforge3/bin/conda' 'shell.zsh' 'hook' ...)")。
# <<< conda initialize <<<

# =============================================================================
# claude-code upgrade helper
# =============================================================================
# Works around pnpm v11 isolated-layout bug where install.cjs writes a 500B
# stub instead of the 198M native binary. Re-running install.cjs after install
# completes fixes it.
claude-upgrade() {
  pnpm i -g @anthropic-ai/claude-code "$@" || return
  local installer
  installer=$(find ~/Library/pnpm/global -path '*claude-code/install.cjs' 2>/dev/null | head -1)
  if [ -n "$installer" ]; then
    node "$installer"
  fi
  command claude --version
}
```

【~/.zshenv 的完整内容】
```bash
. "$HOME/.cargo/env"
```

【~/.zprofile 的完整内容】
```bash
eval "$(/opt/homebrew/bin/brew shellenv)"
```

【完成后请验证,并把结果报给我】
- `echo $SHELL` 是 /bin/zsh
- `which node` 指向 ~/.nvm/versions/node/v*/bin/node
- `uv --version` 可用;`which python` 指向 conda env
- `type claude-upgrade` 能找到该函数
- `time zsh -i -c exit` < 300 ms
- 提醒我两件手动收尾:① 把终端字体切到 Fira Code Nerd Font,否则 P10k 图标乱码;
  ② 我自己运行 `p10k configure` 走一遍向导

以下为人工参考,复刻时无需阅读。十年后自己排错时再看。

2. 配置组件清单

组件作用安装方式
Homebrew包管理(走 USTC 镜像)官方一键脚本
Oh My Zshzsh 框架官方一键脚本,仓库在 ~/.oh-my-zsh
Powerlevel10k主题,含 instant promptgit clone 到 ~/.oh-my-zsh/custom/themes/powerlevel10k
zsh-autosuggestions历史补全git clone 到 ~/.oh-my-zsh/custom/plugins/zsh-autosuggestions
zsh-syntax-highlighting命令高亮git clone 到 ~/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting
nvmNode 版本管理(lazy load)官方脚本到 ~/.nvm,默认 v24 系列
Go~/go 作为 GOPATHbrew
uv替代 pip,配合 miniforge 解释器curl -LsSf https://astral.sh/uv/install.sh | sh
BunJS runtimecurl -fsSL https://bun.sh/install | bash
pnpm包管理,PNPM_HOME=~/Library/pnpmbrew
Miniforgeconda 系 Pythonbrew cask / 官方安装包;解释器路径 ~/miniforge3/bin/python
Fira Code Nerd FontP10k 图标字体brew install --cask font-fira-code-nerd-font

当前实测版本(用于排错对照)

  • Homebrew 5.1.1
  • node v24.14.1
  • pnpm 11.1.2
  • uv 0.8.14
  • go 1.24.1 (darwin/arm64)

文件位置

  • ~/.zshrc 主配置(全文见 §1 prompt 内)
  • ~/.zshenv 内容:. "$HOME/.cargo/env"
  • ~/.zprofile 内容:eval "$(/opt/homebrew/bin/brew shellenv)"
  • ~/.p10k.zshp10k configure 生成,体积约 90KB,可选择从旧机带过来

3. 配置里几个”非显然”的设计

把这些写进 .zshrc 是踩过坑后的成品,迁移时不要轻易删:

  1. P10k instant prompt 必须在文件最顶 提示符立即显示,其余 zshrc 在后台加载。删掉会拖慢启动 ~300 ms。

  2. zstyle ':omz:update' mode disabled + ZSH_DISABLE_COMPFIX=true 关掉 omz 自动更新检查、跳过 compfix 审计,启动再省 ~150 ms。

  3. Terminal theme-report stripping (_disable_terminal_theme_reports) Ghostty / Kiro / cmux 这几个终端会发 ^[?2031l 主题查询序列,泄露到 prompt 会让 P10k 报 “console output” 警告。这段 hook 把首屏跳过、之后逐次清理。

  4. nvm lazy-load nvm.sh 加载要 2 秒,所以我只在 PATH 里塞 default 版本的 bin。真正调用 nvm 命令时再 source 真身。99% 场景不会触发。

  5. Homebrew USTC 镜像 国内不走镜像 brew update 必卡。HOMEBREW_AUTO_UPDATE_SECS=31536000 把自动更新拉到一年一次。

  6. uv 接管 pip / venv alias pip='uv pip'alias venv='uv venv' 让肌肉记忆无缝迁移。

  7. claude-upgrade 辅助函数 pnpm v11 isolated layout 有 bug,装 @anthropic-ai/claude-codeinstall.cjs 会写一个 500B 的桩文件,而不是 198M 的真实二进制。这个函数装完后重新跑一次 install.cjs 修复。

  8. Kiro 集成 只在 TERM_PROGRAM == kiro 时加载,不污染其它终端。


4. 手动安装命令(Claude Code 失败时备用)

# 1. Homebrew(先 export 镜像变量再装,否则会卡 GitHub)
export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.ustc.edu.cn/brew.git"
export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.ustc.edu.cn/homebrew-core.git"
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 2. Oh My Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended

# 3. Powerlevel10k + 两个插件
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
git clone https://github.com/zsh-users/zsh-autosuggestions \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
git clone https://github.com/zsh-users/zsh-syntax-highlighting.git \
  ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

# 4. Nerd Font(P10k 图标)
brew install --cask font-fira-code-nerd-font

# 5. nvm + node
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --lts && nvm alias default lts/*

# 6. uv
curl -LsSf https://astral.sh/uv/install.sh | sh

# 7. bun
curl -fsSL https://bun.sh/install | bash

# 8. pnpm / go
brew install pnpm go

# 9. miniforge
brew install --cask miniforge
conda init zsh

# 10. 覆盖 ~/.zshrc 为 §1 prompt 内给定的内容,然后
exec zsh
p10k configure   # 走一遍向导,生成 ~/.p10k.zsh

5. 善后检查清单

  • echo $SHELL/bin/zsh
  • 终端用了 Nerd Font(否则 P10k 图标会乱码)
  • which node 指向 ~/.nvm/versions/node/v*/bin/node
  • which python 指向 conda env,uv --version 可用
  • claude-upgrade 函数可调用(type claude-upgrade
  • 启动时间合理:time zsh -i -c exit < 300 ms
修改历史