本文档说明如何在一台新的 macOS(Apple Silicon)机器上,用本仓库还原完整的开发环境。
# Homebrew(若未安装,Apple Silicon 默认前缀 /opt/homebrew)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv)"
# —— chezmoi 本体与字体 ——
brew install chezmoi
brew install --cask font-jetbrains-mono-nerd-font # Ghostty / Alacritty / kitty / Neovim 均依赖该字体
# —— 可选:使用 LFS 跟踪文件的仓库需要 Git LFS;普通 Git 仓库不依赖它。
brew install git-lfs && git lfs install
# —— 启动必需工具(首次启动 zsh 即被使用,建议随本节一并装;完整清单与说明见 §4)——
# fzf-tab 无需手动安装:由 zimfw 首次启动时按 dot_config/zsh/dot_zimrc 自动拉取
brew install fzf starship zoxide mise fd ripgrep
# —— 终端入口必需 ——
brew install fish # Alacritty 配置直接使用 /opt/homebrew/bin/fish
# 若使用 Alacritty 的既定入口(Fish -> tmux main):
brew install tmux为什么要在
apply之前:apply后一般会立即exec zsh首次启动(Zim 拉模块、 各工具初始化、补全加载),上述前置若缺装会导致功能明显退化甚至 git 全局断链。 守卫化说明:~/.config/zsh/.zshrc(经 symlink 兼容~/.zshrc)中zoxide/mise/starship的eval均带command -v守卫,rustup/cargo 的 PATH 注入为目录存在性 + 去重双守卫(静态路径, 不再调用brew --prefix子进程),fzf 初始化统一收敛到fzf.zsh(带守卫), 缺装时全部静默跳过、不再报command not found——因此其余体验增强类工具 (bat/lsd/kubectl等,见 §4)完全可以apply之后按需补装, 静默退化不报错。
本仓库引导链共有三次直连 GitHub 的网络动作:chezmoi init 拉取本仓库(方式 A)、
首次启动 zsh 时 zimfw 下载全部 Zim 模块、首次运行 nvim 时 lazy.nvim 安装全部
插件(各插件最新版,lazy-lock.json 已不入库)。弱网/受限网络环境建议在执行下面任何 bootstrap 步骤之前先临时设置代理:
# 示例:本机代理监听 7890(与 dot_gitconfig / ~/.ssh/config 中的代理端口一致)
export https_proxy=http://127.0.0.1:7890
export http_proxy=http://127.0.0.1:7890
export all_proxy=socks5h://127.0.0.1:7890
# 探活:确认代理端口确实在监听,再继续后面的 bootstrap
nc -z 127.0.0.1 7890 && echo "proxy ok" || echo "proxy not listening on 7890"- 代理不在监听时先解决代理本身,或改走直连/镜像;探活通过后再执行
chezmoi init、 首次启动zsh、首次运行nvim。 - 两通道行为不对称:
dot_gitconfig中仅一处按域名限定的 GitHub 代理([http "https://github.com"],对该 URL 匹配的 HTTP/HTTPS 远程均生效;冗余的[https …]/[ssh …]段已删)固定为socks5h://127.0.0.1:7890且无直连回退——代理离线时对 GitHub 的 git 操作会卡住或报Connection refused;~/.ssh/config的ProxyCommand则先探测127.0.0.1:7890, 在线走 SOCKS5、离线自动回退直连。 - 首次启动
zsh时zimfw拉模块走 HTTPS(新机默认无~/.gitconfig即不受 git 代理 影响),此时 shell 侧导出的https_proxy即为其提供代理通道。
# 方式 A:从远程仓库初始化并立即应用(新机器首选)
chezmoi init --apply <user>/<repo>
# 方式 B:源目录已在本机(~/.local/share/chezmoi)时
chezmoi diff # 先预览
chezmoi apply
exec zsh # 重启 shell 使全部配置生效(或重新打开终端)新机器执行 chezmoi apply 时,根目录的 .chezmoiignore 会自动跳过以下内容不渲染到 $HOME(见 layout.md):
- 根级与全部嵌套的
README.md(实际模式为**/*.md(含zsh/README.md、nvim/README.md)—— 仓库文档仅留在源目录,不污染目标机;LICENSE文件(根级与nvim/LICENSE)已删除,**/LICENSE模式防御性保留 docs/—— 本文档所在目录整体不部署*.local/*.local.*/*.bak/**/.DS_Store/**/*.log*/**/node_modules//**/.pnpm-store/等本地覆盖与构建产物(嵌套路径必须带**/前缀,否则只锚定仓库根)- Pi 已知运行时路径:agent permission-mode/sessions/npm/missions/tasks、
auth.json、credentials、models-store 与 workflows state;这组规则是黑名单,不会屏蔽所有未列出的 Pi 源文件 - 机器本地状态与配置:
.config/fish/fish_variables、.codex/config.toml、.claude/settings.json .orca/与.vscode/的忽略条目是防御性模式;仓库中当前没有映射到这两个 target 的 dot-source 目录。根.vscode/的 Git 跟踪规则另见.gitignore。*token*/*secret*/*credential*/*auth.json*/hosts.yml等敏感文件名匹配
注意:
dot_gitconfig不在忽略之列——apply会正常生成~/.gitconfig(历史上的 源名失配行dot_gitconfig/**/dot_git与**/REAMDME.md拼写错误均已修复)。managed目标数随配置与 chezmoi 版本浮动,请以chezmoi managed实测为准,不要依赖历史硬编码数字。详见 layout.md。
因此 chezmoi diff 中不会出现 docs/ 的新增,chezmoi doctor 亦不会告警缺失——属预期行为。
如需排查可执行 chezmoi ignored / chezmoi status 查看被忽略列表。
| 组件 | 行为 | 触发时机 |
|---|---|---|
fish / pi |
dot_config/fish/config.fish(interactive 时初始化 Starship,插件由 fish_plugins 清单管理)、dot_pi/**(Pi 的四个 Git-allowlisted 配置;.chezmoiignore 只屏蔽已知运行时路径,其他本地 Pi 源文件仍可能部署;不提供沙箱)直接生效,均随 apply 写入 $HOME;本文档只覆盖 zsh 栈,其余见 layout.md |
首次启动 fish / pi 时 |
| Zim 框架 | ~/.config/zsh/.zshrc 检测 ~/.zim/zimfw.zsh 缺失时自动下载并 zimfw init 安装 dot_zimrc 中声明的全部模块(详见 dot_config/zsh/dot_zimrc) |
首次启动 zsh |
PATH / brew |
按 dot_zshrc 中守卫逻辑注入 Homebrew 与本地路径(前置 ~/bin 等,cargo/rustup 按目录存在性守卫,详见 dot_config/zsh/dot_zshrc) |
每次启动 zsh |
zoxide / mise / starship / fzf |
按 command -v 守卫 eval 初始化,未安装静默跳过;fzf 键位绑定唯一收敛于 fzf.zsh(详见 dot_zshrc 与 fzf.zsh) |
每次启动 zsh |
zsh 三模块 |
按序 source ~/.config/zsh/aliases.zsh → fzf.zsh(含 fzf 前缀探测与 ~/.cache/zsh/fzf_prefix 缓存)→ sdk.zsh(pnpm / Go / Rust / Docker / kubectl,补全走 ~/.cache/zsh/ 缓存 + zcompile,均有守卫) |
每次启动 zsh |
| Neovim | 首次运行 nvim 时 lazy.nvim 自动 bootstrap 并安装全部插件最新版(lazy-lock.json 已停止跟踪,需网络) |
首次运行 nvim |
mise 工具链 |
mise activate 已挂接;按需执行 mise install 安装 dot_config/mise/config.toml 声明的工具(详见该文件) |
手动执行 |
~/.config/zsh/.zshrc以显式逐文件source加载三模块(aliases.zsh→fzf.zsh→sdk.zsh),顺序即语义,不使用 glob(新掉.zsh文件不会静默改变加载集); 如需禁用sdk.zsh,重命名/移除已部署文件(如mv ~/.config/zsh/sdk.zsh ~/.config/zsh/sdk.zsh.disabled) 或注释dot_zshrc中对应的 source 行。fzf键位绑定只在fzf.zsh内eval "$(fzf --zsh)"一次,~/.zshrc不再重复。详见 shell.md。
| 工具 | 用途 | 安装 |
|---|---|---|
git-lfs |
处理具有 LFS 跟踪文件的仓库;普通 Git 仓库操作不依赖 git-lfs |
brew install git-lfs && git lfs install |
| 工具 | 用途 | 安装 |
|---|---|---|
fzf |
Ctrl-R / Ctrl-T / Alt-C 及所有 f* 函数(frg / fkill / ftm / fl*) |
brew install fzf |
fzf-tab |
补全菜单模糊化(Zim 模块 Aloxaf/fzf-tab) |
无需手动安装,由 zimfw 按 dot_config/zsh/dot_zimrc 的 zmodule Aloxaf/fzf-tab 首次启动时自动安装并加载 |
starship |
提示符(配置为机器本地 ~/.config/starship.toml Catppuccin Mocha,未随仓库分发,跨机需自行拷贝) |
brew install starship |
zoxide |
z 目录跳转 |
brew install zoxide |
mise |
运行时管理(bun / deno / go / node / pnpm) |
brew install mise |
fd |
fzf 默认文件列表命令 |
brew install fd |
ripgrep (rg) |
frg 内容搜索、fd 缺失时的回退 |
brew install ripgrep |
fd未安装时fzf.zsh自动回退到rg --files;fzf本身缺失时按键绑定与f*函数均不可用,但不阻断 shell 启动(有command -v守卫)。
brew install bat lsd htop fastfetch neovim yazi gh lazygit tldr coreutils kubecolor uv rustupcoreutils提供nproc(makes/xargsp的半核并行优先使用它;缺失时回退 macOS 原生sysctl -n hw.ncpu)- Fish 侧:Fish 已作为终端入口依赖安装;另需
brew install fisher——~/.config/fish/的 13 个插件由fish_plugins清单管理(fisher update安装/更新);提示符复用starship、fzf 键位复用fzf.fish(均已在上方依赖中) lsd/htop分别接管ls/topgh的可达性:SSH 侧由~/.ssh/config的Host github.com → ssh.github.com:443负责;gh的 API 走 HTTPS(api.github.com),不受dot_gitconfig那条[http "https://github.com"]影响(该前缀不匹配api.github.com),而是依赖 shell 代理函数(onproxy)导出的https_proxy。Git、SSH 与 shell 代理函数均使用端口7890(详见 dev-tools.md 中的代理配置说明)。
按需补装(别名 / 函数指向的目标,未装时对应功能退化):
# Python lint:ruff_auto 函数的目标
brew install ruff
# Fish netcheck 的本地下载测速工具(不再下载并执行远程 Python 源码)
brew install speedtest-cli
# Android 逆向:jdx / scr 别名的目标(jadx-gui / scrcpy)
brew install jadx scrcpy另需注意:VS Code 及其 code CLI 是 Git 的 core.editor = code --wait 与 clp_cfg / cla_cfg 别名的目标(fzf 的 Ctrl-E 绑定已注释停用,现为 Ctrl-G 走 $EDITOR)。若 Git 操作需要打开编辑器,必须安装 code CLI,或在本机将 core.editor 覆盖为已安装的编辑器;EDITOR=nvim 不会自动覆盖仓库明确设置的 core.editor。
Android NDK(/opt/homebrew/share/android-ndk)、Docker、kubectl / kubecolor、pnpm、onproxy 函数。Zsh 在 kubectl 存在时才定义 k,并在可用时用 kubecolor 包装 kubectl;Fish 同样在 kubecolor 可用时以函数包装 kubectl(故 kg/kl/kd 等 k8s 别名输出带色,与 zsh 一致),且 Fish 无条件定义 k=kubecolor,直接调用 k 需要安装 kubecolor。Zsh/Fish 会在 Cargo bin 目录存在时直接加入 PATH,不会 source ~/.cargo/env。
brew install --cask ghostty alacritty两者需要字体就绪;Ghostty 使用 /bin/zsh,Alacritty 的配置入口需要 /opt/homebrew/bin/fish 与 tmux。Ghostty 为主力,Alacritty 为备用。详见 terminals.md。
逐项确认还原成功:
# chezmoi 本身(先看)
chezmoi doctor # 各项检查通过;.chezmoiignore 导致 docs/README 等不计入 diff 属正常
chezmoi diff # 应用后应为空(或仅剩有意保留的本地差异)
chezmoi ignored # 确认 docs/、README.md 等在忽略列表
# shell 栈
for f in ~/.config/zsh/.zshrc ~/.config/zsh/*.zsh ~/.config/zsh/.zimrc; do zsh -n "$f" || exit 1; done # 语法检查无报错;逐文件(zsh -n 多文件传参时只查首个,实测)
zsh -ic 'exit' # 干净启动无报错
zsh -ic 'type k; echo $EDITOR' # k -> kubectl(kubecolor 包装);EDITOR=nvim
# 〔未装 kubectl 则跳过:type k 报 not found 属预期〕
starship prompt # 渲染 powerline 提示符无报错〔未装 starship 则跳过本项〕
# fzf(含前缀缓存)〔未装 fzf 则本组全部跳过〕
zsh -ic 'echo $FZF_DEFAULT_COMMAND' # 以 fd 开头〔装了 fzf 但未装 fd 则以 rg 开头〕
cat ~/.cache/zsh/fzf_prefix # 应为 /opt/homebrew/opt/fzf(Apple Silicon)〔未装 fzf 时无此文件,跳过〕
zsh -ic 'type frg fkill ftm' # fzf 交互函数已加载
# mise〔未装 mise 则跳过本组〕
mise ls # 列出 bun/deno/go/node/pnpm(未 install 时提示安装)
mise doctor # 可选:检查 mise 健康度
# 编辑器〔首次运行会触发 lazy.nvim 安装需联网,见 §2 代理段〕
nvim --headless +qa # 无插件加载错误
# SSH / GitHub 可达性
cat ~/.ssh/config # 顶部含 Include ~/.orbstack/ssh/config,github.com 走 ssh.github.com:443
git lfs version # 可选:使用 LFS 跟踪文件时确认 Git LFS 可用
git config --get-regexp proxy # 应为 socks5h://127.0.0.1:7890(与 SSH ProxyCommand 7890 统一;
# apply 已部署 ~/.gitconfig,可直接读取)
# 也可直接校验源文件:
# git config --file ~/.local/share/chezmoi/dot_gitconfig --get-regexp proxy日常更新速览:
dot_config/zsh/aliases.zsh提供auto-update(若定义了onproxy函数则先切代理,随后直接委托update-all执行,覆盖目标一致)与更细粒度的update-all [brew|mise|rustup|tldr|uv|sdk|pi](关联数组 7 项,支持参数过滤、失败计数与耗时统计,含mise与pi;失败即红——失败目标打印红色✗与错误摘要、结尾汇总N/M 目标失败并返回非零,成功目标保持绿色✓);验证通过后可按需执行zsh -ic 'auto-update'或zsh -ic 'update-all',详见 maintenance.md 与 dev-tools.md 的对比表及aliases.zsh源码。
全部通过后即可进入日常使用;更多维护流程见 maintenance.md,完整映射见 layout.md。