Zsh plugins are managed by Antidote, configuration links by Dotbot, and Neovim plugins by LazyVim. CLI applications are installed separately from shell startup.
Prerequisites: Git, Zsh, and Python 3 (required by Dotbot).
git clone https://github.com/Maher4Ever/dotfiles.git "$HOME/.dotfiles"
cd "$HOME/.dotfiles"On macOS, install Homebrew, then install the declared tools:
brew bundle --file=Brewfile --no-upgrade
./installOn Linux, either use Homebrew with the same Brewfile, or install equivalent
packages through your distribution. Package names vary (git-delta provides
delta, ripgrep provides rg, neovim provides nvim). Install a recent fzf
with fzf --zsh support (0.51 or newer, also required by zoxide). Git, Zsh, and Python 3 are required;
the other CLI tools enable the corresponding aliases and integrations.
Then run ./install. If Antidote is not installed, setup clones it into
${XDG_DATA_HOME:-~/.local/share}/antidote-manager.
./install links the configuration and runs zsh scripts/setup-shell.zsh to
clone plugins and generate the static bundle. Installation needs network access;
normal shell startup does not download plugins or tools. Without a generated
bundle, the shell still starts and prints the setup command.
The shell setup targets macOS and Linux/WSL, not native Windows PowerShell.
zshrc: tool initialization, plugin loading, completions, aliases, and prompt.zshenv: minimal PATH setup, also used by non-interactive Zsh.zsh/settings.zsh: personal shell, history, and completion preferences.zsh_plugins.txt: plugin manifest, including selected Oh My Zsh components.Brewfile: standalone CLI tools, including Starship, fzf, fnm, uv, and zoxide.scripts/setup-shell.zsh: plugin installation, bundle generation, cached colors, and Rust completions. The bundle also records the Oh My Zsh path so startup does not need to ask Antidote to locate it.zsh/aliases.zsh: explicit Forgit aliases that do not override OMZ Git aliases.zsh/dirhistory.zsh: directory navigation with normal editing keys preserved.
Generated files live outside the checkout:
- Plugin repositories:
${XDG_DATA_HOME:-~/.local/share}/antidote. - Static bundle:
${XDG_CACHE_HOME:-~/.cache}/dotfiles/zsh_plugins.zsh. - Completion cache:
${XDG_CACHE_HOME:-~/.cache}/zsh. Completion result data lives in itscachesubdirectory (formerly~/.zcompcache). - Color data:
${XDG_CACHE_HOME:-~/.cache}/dotfiles/ls-colors.
Custom ANTIDOTE_HOME, ANTIDOTE_SOURCE, and XDG directories are supported;
use the same values during setup and shell startup. ANTIDOTE_SOURCE points
to an existing antidote.zsh file when it is installed in a nonstandard location.
After editing the plugin manifest, regenerate the bundle:
zsh ~/.dotfiles/scripts/setup-shell.zshTo update plugins, rebuild generated shell data, and run regression checks:
dotfiles-updateTo also update Homebrew and the CLI tools listed in the Brewfile:
dotfiles-update --tools./install links this command into ~/.local/bin. You can also run
zsh ~/.dotfiles/scripts/update.zsh directly. It stops at the first failed step
and reports the error. Updates already completed are not rolled back; correct
the error and rerun. Python 3 and the installed Brewfile tools are required for
the regression checks. Homebrew is only required with --tools.
The setup step generates vivid's snazzy colors and Rust completions when the
corresponding tools are installed. Run it after installing/updating rustup or
changing its default toolchain. Normal shell startup does not run those generators
or brew install / brew upgrade.
Install the Brewfile and run zsh scripts/setup-shell.zsh, then open a new
terminal. Zinit and its annexes are no longer loaded. Existing Zinit files are
left on disk so rollback and recovery of old runtimes remain possible.
Once verified, archive the old tree before removing it. On this machine the
legacy tree was archived and verified under
~/.local/state/dotfiles/backups/zinit-*.tar.gz, then removed from
~/.local/share/zinit. The archive includes the former Zinit-managed pyenv files.
Standalone runtime installations are unaffected. To restore, extract the archive
into ~/.local/share when there is no existing zinit directory there.
- Node uses fnm and automatically switches versions on directory changes.
Use
.node-versionor.nvmrcin projects, andfnm installfor missing versions. NVM is no longer initialized; its installations are left untouched. - Python projects use uv; no pyenv shims are initialized. Existing standalone
pyenv installations/data are left untouched. Use
uv python install 3.13to install a needed version,uv python pin 3.13in a project,uv syncfor dependencies, anduv run pythonoruv run pytest. This is a project workflow, not a global replacement ofpython/python3. Keep Homebrew Python when other packages require it. - zoxide supplies
z(jump) andzi(interactive selection). To migrate an existing zsh-z database once, runzoxide import --merge zsh-z. This leaves the original~/.zintact; do not repeat routinely, because it merges scores. - CLI tools previously fetched by Zinit now come from the Brewfile, including
git-recentandgit-quick-stats.git-myandgit-recallare no longer loaded. Use Lazygit or Forgit's log/branch pickers for those workflows.paulirish/git-openstays with Antidote'skind:path: Homebrew's identically named formula is a different implementation. - Plugins load synchronously, making aliases available immediately. Syntax highlighting loads last, after completion and widget setup.
- Ctrl-R retains the syntax-colored
history-search-multi-wordpicker. fzf completion is retained without replacing Ctrl-R/Ctrl-T/Alt-C bindings. - Plugin auto-updates are disabled; updates are explicit.
Keep the old checkout/branch and Zinit data until you are satisfied. Because Dotbot uses symlinks, changing the checked-out branch changes what new shells load. Do not switch branches with uncommitted edits unless they are preserved.
- Ctrl-R: the existing syntax-colored history picker.
- Tab: fuzzy completion with fzf-tab for files, directories, Git branches, and other Zsh completions. Type to filter and press Enter to select.
- duf: a readable overview of filesystem capacity and free space.
- History retains up to 100,000 entries on disk, with 120,000 in memory to give duplicate-first expiry room to work. Existing history is preserved; previously expired entries cannot be recovered by increasing the limit.
- z / zi: zoxide directory jump / interactive selection.
- Alt-arrows: directory navigation where your terminal sends distinct escape
sequences. Normal Up/Down history and Meta-B/F word movement are preserved.
dback,dforward,dup, andddownwork regardless of terminal mapping. - cat: plain system cat. Run
batexplicitly for syntax-highlighted viewing. - lzg / lzd: Lazygit / Lazydocker.
- Alias reminders use you-should-use. The old Python-based alias-tips hook is no longer loaded.
OMZ owns the ordinary g* Git aliases. Forgit uses distinct fg* names:
| Operation | Ordinary Git (OMZ) | Interactive picker (Forgit) |
|---|---|---|
| Add files | ga |
fga |
| Diff | gd |
fgd |
| Log | glo |
fglo |
| File checkout | Use git restore |
fgcf |
| Branch selection | gsw |
fgsw or fgcb |
| Stash inspection | Use git stash show |
fgss |
| Ignore-file generation | — | fgi |
In particular, gcf means git config --list, gss means git status --short,
and gcb creates a branch with git checkout -b. The full Forgit mapping is in
zsh/aliases.zsh; all of its former default alias names get an f prefix.
SSH-agent integration honors an existing agent (macOS, forwarded, or another
provider). When none is usable, the plugin can start its own agent. It does not
automatically load private keys; use your OS/provider or ssh-add explicitly.
Debian package aliases load only on Debian-family Linux with apt-get available.
The unused OMZ correction/spectrum libraries and eager clipboard/functions entries are removed; use-omz provides lazy helpers. Completion, miscellaneous, and Git libraries remain because they provide behavior beyond duplicated options.
zsh -f -n zshrc
zsh -f -n zshenv
zsh -f -n zsh/settings.zsh
zsh -f -n zsh/antidote.zsh
zsh -f -n zsh/aliases.zsh
zsh -f -n zsh/dirhistory.zsh
zsh -f -n scripts/setup-shell.zsh
bash -n install
python3 scripts/check-shell.py
python3 scripts/check-update.pyThe smoke check requires the Brewfile tools and generated plugin bundle. It runs real interactive Zsh in a pseudo-terminal with an isolated HOME, checks fallback startup without plugins, then checks plugins, completions, aliases, widget bindings, and tool availability without Zinit. It also checks inherited SSH-agent handling, editing keys in Apple Terminal/Ghostty/iTerm profiles, and Node version switching when two fnm versions are available. It does not modify your history.
To profile all initialization, open a terminal with PROFILE_STARTUP=true zsh.
Completion security checks remain enabled on every startup. In the profile,
use-omz's deferred wrapper and the real compinit appear under the same name;
the two calls do not mean completion was initialized twice.
Git uses SSH commit signing, delta, zdiff3 conflict markers, and automatic
pruning of stale remote-tracking branches when fetching. Credentials use the
system's configured helper: macOS Apple Git supplies Keychain. On Linux,
configure a secure credential helper appropriate to the desktop or Git
Credential Manager; the shared config does not persist plaintext credentials.
Identity profiles match /Volumes/code/personal/ and /Volumes/code/ngrave/
on this Mac, plus ~/code/personal/ and ~/code/ngrave/ on other machines.
Repositories elsewhere use the default identity unless configured locally.
For a work repository outside those locations, explicitly select the work
profile inside that repository:
git config --local include.path ~/.dotfiles/git/ngrave.gitconfig
git config --show-origin --get user.email
git config --show-origin --get user.signingkeyThe personal profile uses ~/.ssh/id_ed25519_personal.pub. Its private key must
be available through the corresponding key file or your SSH agent for signing.
- Font:
FireCodeNerdFont-Regular.ttf - Color Theme:
Tokyo Nightthrough Gogh
- Font:
FireCodeNerdFont-Regular.ttf - Color Theme: Dracula