Mac 开发工具流配置记录

最近给自己的 Mac 从头整了一套开发工具链,从终端模拟器到编辑器,从 dotfiles 管理到 shell 美化,折腾了大概一个周末。之前一直是零散地用,换个设备就要重新配一遍,这次用 chezmoi 统一管理,顺便尝试了一些新的工具。

这篇文章记录了我目前的工具栈和配置思路,主要面向 Unix 系统(Mac),后续考虑迁移到 Linux。

1. Dotfiles 与包管理

Dotfiles 管理器 —— chezmoi

Unix 系统里,各类工具的配置几乎都以隐藏文件的形式存放在 ~/.config 或家目录下。Git、Zsh、Vim、tmux……所有配置都是纯文本的 dotfiles。问题在于:如何跨设备同步这些配置,同时保护好 API Key 等敏感信息?

常见的做法是建一个 Git 仓库,用符号链接(ln -s)把配置文件映射到家目录,或者用 Stow/RCM 这类工具管理。但符号链接的方案有几个痛点:

  • 多设备配置差异不好处理(Mac 和 Linux 服务器可能需要不同的配置)
  • 机密信息(API Key、Token)不能直接放公开仓库
  • 下载后需要手动调整权限和路径

chezmoi 用一种更像是「模板引擎」的方式解决了这些问题。它不盲目地复制或链接文件,而是根据系统变量、模板语法、机密管理器来动态生成最终的 dotfiles。

日常使用流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 安装
brew install chezmoi

# 初始化仓库(存放位置 ~/.local/share/chezmoi)
chezmoi init

# 添加需要管理的配置文件
chezmoi add ~/.zshrc
chezmoi add ~/.config/nvim/init.lua

# 编辑(使用 $EDITOR 指定的编辑器)
chezmoi edit ~/.zshrc

# 查看修改差异
chezmoi diff

# 应用修改到实际配置文件
chezmoi apply

一个小细节:chezmoi edit 修改的是 chezmoi 仓库里的副本,必须执行 chezmoi apply 才会写入实际路径。这个机制给了你在应用前对比确认的机会,不容易翻车。

如果配置文件本身是符号链接,chezmoi add 需要加 -f 参数才能跟随符号链接读取实际文件内容。

包管理器 —— Homebrew

macOS 上开发,Homebrew 基本是必装的。官方安装脚本在国内网络环境下经常拉不下来,我用了 gitee 上的镜像脚本:

1
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

装完之后在 .zshrc 里加了几个优化项:

1
2
3
4
5
6
# 关闭 Homebrew 自动更新(需要时手动 brew update)
export HOMEBREW_NO_AUTO_UPDATE=1
# 关闭自动显示更新提示
export HOMEBREW_NO_ENV_HINTS=1
# 关闭 analytics(隐私+速度)
export HOMEBREW_NO_ANALYTICS=1

这几个开关能让每次 brew install 快不少,不用等它自动 update。

2. 终端与 Shell 层

这一层是日常交互最频繁的地方,从终端模拟器、Shell、插件到提示符。

终端模拟器 —— Alacritty

不用Ghosty、Kitty、Iterm这些终端工具而是选 Alacritty 的理由是,不太希望有太多我用不到的功能被下载,或者说一个功能可以同时由两个工具实现。

例如终端复用,大多数终端自带终端复用,但是由于我自己常用tmux,所以使用自带终端复用的终端模拟会比较冗余,还有一些类似的原因。

Alacritty是Rust编写的,速度更快,内存占用更小

安装:

1
brew install alacritty

macOS 上首次打开需要在系统安全性设置里放行。另外原版图标确实不太好看,可以参考这个知乎链接换一个。

我的配置如下(~/.alacritty.toml),更多的配置可以参考官方文档:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[window]
# 窗口尺寸(字符列数 × 行数)
dimensions = { columns = 80, lines = 24 }
# 窗口内边距
padding = { x = 4, y = 0 }
# 背景不透明度 + 模糊
opacity = 0.2
blur = true
# 启动时全屏
startup_mode = "Fullscreen"
title = " My alacritty terminal "

[font]
normal = { family = "JetBrainsMono NF", style = "Regular" }
bold = { family = "JetBrainsMono NF", style = "bold" }
italic = { family = "JetBrainsMono NF", style = "italic" }
bold_italic = { family = "JetBrainsMono NF", style = "bold italic" }
size = 18

[cursor]
# 线状光标,闪烁
style = { shape = "Beam", blinking = "On" }

键盘绑定配置了 macOS 风格的快捷键(Cmd+C/V 复制粘贴、Cmd+F 查找、Cmd+N 新建窗口等),这里就不全贴了。

Shell 核心 —— Zsh + Antidote

没有用 Oh My Zsh。虽然它确实很方便,但启动速度不太理想,而且装载了一大堆你可能永远用不上的东西。

最终方案:原生 Zsh + Antidote 作为插件管理器。

Antidote 对比 Oh My Zsh 和 zinit,优势是简洁、启动快、支持 ohmyzsh 插件桥接。安装:

1
brew install antidote

在 .zshrc 中的初始化逻辑:

1
2
3
4
5
6
7
8
9
10
# antidote 初始化
source $(brew --prefix antidote)/share/antidote/antidote.zsh
# 插件配置文件
zsh_plugins=${ZDOTDIR:-~}/.zsh_plugins
# 自动生成插件缓存
if [[ ! ${zsh_plugins}.zsh -nt ${zsh_plugins}.txt ]]; then
(antidote bundle <${zsh_plugins}.txt >|${zsh_plugins}.zsh)
fi
# 加载所有插件
source ${zsh_plugins}.zsh

缓存机制是关键:只在 .zsh_plugins.txt 有更新时才重新生成 .zsh_plugins.zsh,日常启动直接加载缓存的 zsh 文件,几乎感觉不到延迟。

插件列表(~/.zsh_plugins.txt):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 语法高亮
zsh-users/zsh-syntax-highlighting

# 自动补全建议
zsh-users/zsh-autosuggestions

# 历史命令搜索
zsh-users/zsh-history-substring-search

# 快速目录跳转
agkozak/zsh-z

# 使用 ohmyzsh 插件(桥接器)
getantidote/use-omz
ohmyzsh/ohmyzsh path:plugins/copyfile
ohmyzsh/ohmyzsh path:plugins/copypath
ohmyzsh/ohmyzsh path:plugins/copybuffer
ohmyzsh/ohmyzsh path:plugins/extract
ohmyzsh/ohmyzsh path:plugins/colored-man-pages

几个常用的 ohmyzsh 插件通过桥接器 use-omz 引入,比直接加载整个 ohmyzsh 库更省内存。zsh-z 用来快速跳转目录,extract 一键解压各种压缩包,都是高频使用的。

.zshrc 中还有一些非工具链的配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 关闭 Homebrew 自动更新(前面提过)
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_ENV_HINTS=1
export HOMEBREW_NO_ANALYTICS=1

# 设置默认编辑器
export EDITOR="nvim"

# nvm 加载
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"

# 自定义命令路径
export PATH="$HOME/.local/bin:$PATH"

提示符 —— Starship

Starship 是一个用 Rust 写的跨 shell 提示符工具,特点是快,而且开箱自带漂亮的预设主题。

1
brew install starship

在 .zshrc 中初始化:

1
eval "$(starship init zsh)"

我直接用了官方预设 Pastel Powerline,可以在官方文档查看社区预设配置和具体的配置方法。这个预设会显示用户信息、当前目录、Git 分支和状态、各类语言版本以及当前时间,色彩分段很有层次感。用 chezmoi 管理后全设备统一。

字体 —— Nerd Font

Nerd Font 是终端里显示图标和特殊符号的基础,Alacritty 和 Starship 都依赖它。

1
2
3
4
# 先搜一下有哪些字体可以使用
brew search nerd-font
# 选 JetBrains Mono
brew install --cask font-jetbrains-mono-nerd-font

JetBrains Mono —— 字形清晰,等宽效果舒服,对编程场景优化得很好。

3. 终端复用器 —— Tmux

tmux 对于开发来说基本是刚需:一个会话可以切分多个窗格,断开 SSH 后工作环境还在(服务器训练友好)。

安装:

1
brew install tmux

我的配置(~/.tmux.conf):

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
# 前缀键改为 Ctrl+a(比默认的 Ctrl+b 更顺手)
unbind C-b
set -g prefix C-a
bind C-a send-prefix

# 基础行为
set -g default-terminal "tmux-256color"
set -g history-limit 10000
set -g escape-time 0
set -g focus-events on
set -g mouse on

# 索引从1开始(而不是0)
set -g base-index 1
setw -g pane-base-index 1
set -g renumber-windows on

# 窗格分割快捷键
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"
bind c new-window -c "#{pane_current_path}"

# 窗格切换(vim 方向键风格)
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

# 复制模式(vi 风格)
setw -g mode-keys vi
bind Enter copy-mode
bind -T copy-mode-vi v send -X begin-selection
bind -T copy-mode-vi y send -X copy-selection-and-cancel

# 快捷操作
bind r source-file ~/.tmux.conf \; display "Config reloaded!"
bind x kill-pane
bind X kill-window

配色用的是 Catppuccin Mocha 风格的暗色调(#1e1e2e 底色、#89b4fa 蓝色高亮),状态栏简洁地显示 session 名称和当前时间。

几个关键选择:

  • 前缀键改成 Ctrl+a,比默认的 Ctrl+b 好按很多(可以选一个自己习惯的)
  • 如果使用本地 tmux 嵌套服务器 tmux 的话,最好两边的前缀使用不一样的
  • 窗格索引从 1 开始,和键盘数字区对齐
  • 复制模式用 vi 键位,和 Neovim 操作习惯保持一致

4. 编辑器 —— Neovim

文本编辑器选择会比较多,简单一些的可以用nano,也有用 nvim 或者 vim 的

  • 用nano的一般是在终端进行一些简单的文本编辑工作,不会进行复杂的代码编辑,所以不需要过多文本编辑优化,同时nano的快捷键提示也比较友好,使用简单
  • 如果要进行复杂的编辑工作,Vscode毫无疑问是最简单入门最实用的工具,社区插件覆盖全,全球用户认证,给到夯。
  • btw,如果想折腾一下或者geek play的话,vim类编辑器是一个不错的选择,vim和nvim都是不错的选择,也可以选择想类似Lazyvim这种开箱即用的编辑配置,vim用习惯了确实会提高编码效率,但是对于目前vibe coding盛行的情况,相比与高效输入大段代码,我们似乎更需要一个好的终端代码浏览器(如果在终端使用claude code这类的agent工具而且不想多打开一个Vscode的话),这种情况下nvim也是一个不错的选择。

安装与初始化

1
brew install neovim

kickstart.nvim 不是发行版,而是一个教学性质的起点配置。它最大的好处是每一行配置你都能读懂,从 init.lua 顶部读到底部,你知道你的编辑器在做什么。

我先 fork 了一份到自己的 GitHub,然后 clone 到本地作为 nvim 配置目录:

1
git clone git@github.com:kzzzza/kickstart.nvim.git "${XDG_CONFIG_HOME:-$HOME/.config}"/nvim

为了用 chezmoi 统一管理,删掉了不需要的仓库文件(.git*、doc/、LICENSE、README),只保留核心配置:

1
2
3
4
5
6
7
.config/nvim/
├── .stylua.toml # Lua 格式化配置
├── init.lua # 核心配置文件
├── lazy-lock.json # lazy.nvim 插件版本锁定
└── lua/
├── custom/plugins/ # 自定义插件
└── kickstart/ # kickstart 基础插件配置

插件体系

使用 lazy.nvim 作为插件管理器。以下列出每个插件的选型理由和核心配置:

编辑器基础体验:

插件 作用 选型理由
tokyonight.nvim 配色主题 护眼暗色系,关掉斜体注释,用 tokyonight-night 变体
which-key.nvim 快捷键提示 记不住快捷键时的救命稻草
mini.nvim 状态栏 / 文本对象 / 环绕编辑 轻量替代,一个包解决三个需求
gitsigns.nvim Git 变更标记 行号区显示增删改,支持 hunk 跳转
todo-comments.nvim TODO 注释高亮 代码里的 TODO、FIX 标记高亮

代码智能:

插件 作用
nvim-lspconfig + mason.nvim LSP 配置与自动安装
blink.cmp 自动补全(Rust 实现的模糊匹配)
conform.nvim 代码格式化(保存时自动运行)
nvim-treesitter 语法高亮与结构化理解

导航与搜索:

插件 作用
telescope.nvim 模糊查找(文件、符号、grep、帮助文档)
guess-indent.nvim 自动检测缩进

Snippet:

  • LuaSnip 作为 snippet 引擎,配合 blink.cmp 使用

几个配置细节

init.lua 中的一些关键设置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
-- leader 键设为空格
vim.g.mapleader = " "
vim.g.maplocalleader = " "

-- 启用 Nerd Font 图标
vim.g.have_nerd_font = true

-- 行号 + 相对行号
vim.o.number = true
vim.o.relativenumber = true

-- 系统剪贴板同步
vim.o.clipboard = "unnamedplus"

-- 智能大小写搜索
vim.o.ignorecase = true
vim.o.smartcase = true

-- 实时预览替换
vim.o.inccommand = "split"

光标上下保留 10 行 (scrolloff = 10),鼠标模式打开方便分屏拖拽,方向键禁用强迫自己用 hjkl (虽然偶尔还是会按错)。

格式化用的 conform.nvim,保存时自动运行。目前只配了 Lua(用 stylua),后续加 Python/Rust 时再加对应 formatter。

5. 命令行工具

除了上述大件,还有一些日常高频使用的小工具:

1
2
3
4
5
brew install ripgrep   # grep 的 Rust 替代,速度飞起
brew install fd # find 的 Rust 替代,语法更友好
brew install bat # cat 的替代,语法高亮 + 行号
brew install eza # ls 的替代,色彩 + 图标
brew install rtk # Claude Code 的 Token 优化代理

6. TODO

目前这套配置还有几个想做的补充。如果没做那就是专心做项目没花更多时间折腾工作流了(doge)。

  • Linux 适配:目前 chezmoi 的配置主要面向 macOS,还没有针对 Linux 个人 PC 和服务器端做差异化配置。chezmoi 本身就支持按系统变量生成不同内容,后续需要用模板语法把 Mac 和 Linux 的分支分开。
  • 一键安装脚本:手写一个 install.sh,在新机器上跑一遍就能装好所有依赖(Homebrew → chezmoi init → chezmoi apply → 装字体和工具链)。理想情况下,换电脑只需要 git clone + 一句 ./install.sh。
  • 密钥信息管理 chezmoi对于API等一些隐私信息配置文件可以做加密,后续探索一下,可以将模型的API或者服务器地址这些私密化的信息加密一下,也使用chezmoi统一管理。
  • dotfiles 仓库公开:目前 chezmoi 仓库还是私有的,等把敏感信息彻底剥离干净(确认 API Key、Token 都没有硬编码),打算把完整的 dotfiles 在 GitHub 公开,也方便别人参考。