自包含、离线优先的 dotfiles。无插件管理器、无子模块、安装时不依赖任何外部工具——./install 只是一个小 bash 脚本,把文件软链到 $HOME 并跑几个安装后钩子。
入库的内容都是通用配置;每台机器自己的密钥和环境变量放在 本地(不入库) 那一节列出的 gitignored 文件里。
根目录只有 install 和 README.md,其余全部是文件夹:
.
├── install # bash 入口 -> scripts/install.sh
├── README.md
├── bash/ # bashrc(如果系统装了 zsh 就 exec 过去)
├── git/ # gitconfig, gitignore_global
├── zsh/ # zshrc, p10k.zsh, p9k.zsh, vendor/* (oh-my-zsh, p10k, p9k, …)
├── vim/ # vimrc, autoload/plug.vim, plugins-vendor/*
├── vscode/ # settings.json, keybindings.json, extensions.txt, vsix/
├── fonts/ # MesloLGS NF + License
├── local/ # 仅本机用的 env.zsh / gitconfig.local(gitignore),以及 *.example 模板
└── scripts/ # install.sh, package-for-offline.sh, update-vendor.sh, …
./install 只负责把这些文件软链到 $HOME(链接表见 scripts/install.sh)。zsh/vendor/ 与 vim/plugins-vendor/ 下面的所有内容都已经作为普通文件入库——没有 git 子模块,也没有 upstream 的提交历史。
- Git、Bash 4.2+(RHEL 7 自带的就够)、coreutils。
- Zsh 作登录 shell(可选,但本套配置默认按这个写)。
- 安装期不需要联网:
- Zsh 插件 在
zsh/vendor/<name>/下,纯文件。 - Vim 插件 在
vim/plugins-vendor/<name>/下,纯文件。 - MesloLGS NF 字体 在
fonts/下入库。 - VS Code 1.85.2 扩展 在
vscode/vsix/*.vsix下入库;codeCLI 必须能在PATH里找到(或者用VSCODE_CLI显式指定)。SKIP_VSCODE_EXTENSIONS=1可以跳过这一步。
- Zsh 插件 在
git clone <repo> ~/dotfiles
cd ~/dotfiles
./install # 幂等;已经装好的机器再跑 ~3s./install 直接 exec 到 scripts/install.sh(一个~110 行的 bash 脚本,dotbot 替身),执行顺序:
- 如果
local/gitconfig.local不存在,从local/gitconfig.local.example复制一份(参考 本地(不入库))。 - 清掉
$HOME顶层那些断掉的符号链接。 - 把仓库里的文件软链到
$HOME:~/.vimrc→vim/vimrc,~/.vim→vim/~/.zshrc→zsh/zshrc,~/.p10k.zsh→zsh/p10k.zsh,~/.p9k.zsh→zsh/p9k.zsh~/.bashrc→bash/bashrc(带 force:原地的非软链文件会被直接覆盖,介意的话先备份)~/.gitconfig→git/gitconfig,~/.gitconfig.local→local/gitconfig.local,~/.gitignore_global→git/gitignore_global~/.fonts→fonts/~/.config/Code/User/settings.json→vscode/settings.json,keybindings.json同理
- 校验
fonts/下的 Meslo TTF 是否齐全,刷一次fc-cache(默认无-f,没改字体就跳过)。 - 用
code --list-extensions --show-versions跟vscode/extensions.txt对账,只对未装或版本不匹配的扩展真正调用code --install-extension,已经是目标版本的直接 skip。
可调环境变量:
| 变量 | 作用 |
|---|---|
DRY_RUN=1 |
只打印动作,不修改文件系统 |
SKIP_MESLO_FONTS=1 |
跳过字体校验 + fc-cache |
SKIP_VSCODE_EXTENSIONS=1 |
跳过 VS Code 扩展安装 |
VSCODE_CLI=/path/to/code |
手动指定 code 可执行路径(绕开自动检测) |
~/.bashrc 与 ~/.gitconfig.local 用 force 语义:如果对应位置已经有非软链的真实文件,会被无备份直接删除。介意的话请先手动备份。
离线机器没法 git pull。整个仓库现在是纯文件(无子模块),打包就是一条 tar:
有网那台:
cd ~/dotfiles
git pull
scripts/package-for-offline.sh # 输出 ../dotfiles-<sha>-<时间戳>.tar.gz
# 或者更小(不带 .git,~131 MB 而非 ~420 MB):
NO_GIT=1 scripts/package-for-offline.sh离线那台:
mv ~/dotfiles ~/dotfiles.bak.$(date +%s)
tar -xzf dotfiles-<sha>-<时间戳>.tar.gz -C ~/
cd ~/dotfiles && ./install整个过程没有任何 git submodule update 步骤——vendor 目录就是普通文件。第二次起 ./install 全部幂等,约 3 秒。
只能在有网机器上跑:
scripts/update-vendor.sh <vendor 路径> <git URL> [<ref>]
# 示例:
scripts/update-vendor.sh vim/plugins-vendor/nerdtree https://github.com/preservim/nerdtree.git master
scripts/update-vendor.sh zsh/vendor/powerlevel10k https://github.com/romkatv/powerlevel10k.git v1.20.0脚本会克隆 upstream,删掉它的 .git/,把目标目录整个替换掉,并把改动 stage 起来。用 git diff --cached <path> 复核,再提交:
git commit -m "chore(vendor): update <path> to <ref>"下面这些文件 永远不要入库(已经写在 .gitignore)。仓库只提供 *.example 模板,第一次 ./install 会自动从模板复制成真实文件:
| 文件 | 入库? | 用途 |
|---|---|---|
local/gitconfig.local.example |
是 | Git 身份模板(user.name / user.email) |
local/gitconfig.local |
否 | 真实的 git 身份;./install 首次跑时从模板复制,链到 ~/.gitconfig.local |
local/env.zsh.example |
是 | 本机 zsh 环境模板 |
local/env.zsh |
否 | 代理、PATH、机器密钥等;zsh/zshrc 末尾会 source 它 |
fonts/MesloLGS NF *.ttf |
是 | 入库的 Meslo + MesloLGS NF License.txt(Apache 2.0) |
绝对不要把 local/gitconfig.local 或 local/env.zsh 提交。
插件以普通目录形式放在 vim/plugins-vendor/<name>/,由 vim-plug 通过本地路径加载(vim/vimrc 里写的):
Plug '~/.vim/plugins-vendor/nerdtree'
" ...plug#end() 会把每个目录加到 &runtimepath,所以完全不需要跑 PlugInstall。
Vim 版本与 easycomplete:vim-easycomplete 需要较新的 Vim(含 v:null、v:true/v:false、job、timer 等,约 Vim 8.0+)。vim/vimrc 在检测到环境不支持时会自动不加载该插件,避免在 RHEL 7 等自带 Vim 7.4 的机器上整屏 E121/E15;其余插件仍正常加载。若需要 LSP 补全,请在该机安装新版 Vim 后再用。终端光标序列 &t_SR 等在旧版上可能不存在,配置里已用 exists('&t_SR') 等形式做了探测,避免 E355。
离线注意:
vim-easycomplete在vim/plugins-vendor/vim-easycomplete/autoload/easycomplete/installer/*.sh里有一堆 LSP 服务器(rust-analyzer、jdtls、omnisharp…)的下载脚本,会用curl联网。在离线机器上不要执行:InstallLspServer;要么提前在有网机器上准备好 LSP 二进制,要么放弃对应语言的补全功能。
Powerlevel10k 要求 zsh >= 5.1。如果 $ZSH_VERSION 太老(典型场景:RHEL/CentOS 7 自带 5.0.2,且不允许升级 zsh),zsh/zshrc 会改用一个手写的小 prompt:
zsh/vendor/powerlevel10k/——zsh >= 5.1时使用,配置文件zsh/p10k.zsh(链到~/.p10k.zsh)。zsh/prompt-fallback.zsh——zsh < 5.1时默认使用。基于vcs_info+ 普通 zsh prompt 转义;两行布局:第一行user@host cwd (git-branch±)+ 右侧[exit] HH:MM:SS,第二行光标前❯(成功为绿色,失败为红色)。不依赖 nerd font / UTF-8 locale,所以即便LANG=C也是可见的。zsh/vendor/powerlevel9k/仍然随仓库分发,但不再默认加载——它的functions/icons.zsh大量使用$'\uXXXX'转义,在 zsh 5.0.x + 非 UTF-8 locale 下解析阶段就会被截断为空,最终图标 / 分隔符 / 颜色全部丢失,prompt 看起来像“空”。如果你想再尝试 P9K,导出DOTFILES_USE_P9K=1后启动 zsh,会沿用旧的zsh/p9k.zsh+ 消毒逻辑。
两套主要主题(P10k / fallback)都不强求 nerd font;只有 P10k 默认那套图标体验需要 MesloLGS NF(仓库 fonts/ 已经带)。zsh/zshrc 顶部的 P10k instant-prompt 缓存块加了同样的 zsh 版本守卫,5.0.2 那台不会再看到 "minimum required version is 5.1" 的红字。
字体细节(具体哪些 TTF 入库、IDE 端怎么配字体)见 fonts/README.md。
简版:在 Cursor / VS Code 跑 IDE 的那台机器的 User settings.json 里加:
{
"terminal.integrated.fontFamily": "'MesloLGS NF', monospace",
"terminal.integrated.fontSize": 14
}也可以参考官方的 Powerlevel10k fonts。