A framework-free macOS dev environment. Every piece is a plain file you can read and edit — no Oh My Zsh, no Prezto.
| Layer | Tool |
|---|---|
| Shell | zsh |
| Plugins | antidote |
| Prompt | powerlevel10k (or starship — swap below) |
| Editor | Neovim + lazy.nvim |
| Terminal | iTerm2 (profile + Nerd Font) |
| Installer | install.sh (symlinks, dry-run by default) |
On a fresh Mac, top to bottom:
# 1. Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 2. Clone
git clone https://github.com/arunraman/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 3. Install every package (shell tools, neovim, CLIs, Nerd Font)
brew bundle --file=Brewfile
# 4. Link the config into $HOME
./install.sh # DRY RUN — prints exactly what it would do, changes nothing
./install.sh --apply # actually symlink
# 5. Start the new shell
exec zshStep 4 is safe to run first. ./install.sh with no flags only prints the
plan. Nothing is written until you add --apply, and any file already in the way
is moved to ~/.dotfiles-backup/<timestamp>/ before the symlink is created — so
re-running is harmless and reversible.
What install.sh deliberately does not do: change your login shell, run
brew, or touch ~/.zprezto. Change your shell yourself if needed:
chsh -s $(which zsh).
install.sh drops a Dynamic Profile into iTerm's
config folder. iTerm loads it live (no restart):
- Settings → Profiles → pick Gargantua.
- Optionally right-click it → Set as Default.
The profile already points at the MesloLGS NF font (installed by the Brewfile) so the prompt's icons render. If you see boxes/tofu instead of icons, see Troubleshooting.
| You type | You get |
|---|---|
<Tab> |
fuzzy completion menu (fzf-tab) with file/dir previews |
Ctrl-R |
fuzzy search through command history |
Ctrl-T |
fuzzy-pick a file and insert its path |
Alt-C |
fuzzy-pick a directory and cd into it |
z <keyword> |
jump to the most-used dir matching the keyword (zoxide) |
ls ll la lsd lt |
eza: icons, git column, lt = tree |
| start a line with a space | keep that command out of history |
Autosuggestions (grey ghost text, → to accept) and syntax highlighting are on
by default.
Leader key is ,.
| Key | Action |
|---|---|
,e |
toggle file tree (neo-tree) |
,ff |
find files (telescope) |
,fg |
live grep across the project |
,fb |
switch buffer |
,t |
toggle symbol outline (aerial) |
gcc |
comment/uncomment line |
First launch installs everything automatically — open nvim, let lazy.nvim and
mason finish, then run :checkhealth if anything looks off. Full plugin list is
in nvim/lua/plugins/.
Everything is a symlink back into this repo, so editing the linked file in $HOME
is editing the repo — then commit.
| Want to… | Edit |
|---|---|
| Add a shell alias | zsh/.zalias |
| Add a shell function | zsh/.zfunc |
Add an env var / $PATH entry |
zsh/.zexports |
| Add a zsh plugin | add a user/repo line to .zsh_plugins.txt, restart shell |
| Add a Neovim plugin | drop a spec file in nvim/lua/plugins/ |
| Change prompt style | run p10k configure (rewrites p10) |
| Link a new dotfile | add it to the LINKS array in install.sh |
Machine-local / secret settings (proxies, work tokens) go in ~/.zextra.
.zshrc sources it if it exists; it is never committed.
powerlevel10k is active by default. starship is also installed and configured (starship.toml) as a drop-in alternate:
- In .zsh_plugins.txt: comment out
romkatv/powerlevel10k. - In .zshrc: comment the p10k instant-prompt block (top) and the
source ~/.p10k.zshline (bottom); uncomment thestarship init zshblock. exec zsh.
Reverse the steps to go back.
Tab does nothing / command not found: _setup on Tab
The completion system or fzf isn't available. Confirm brew bundle ran
(which fzf) and that .zshrc reaches its compinit line. exec zsh to reload.
Prompt shows boxes (tofu) instead of icons
iTerm isn't using a Nerd Font. Settings → Profiles → Text → Font →
MesloLGS NF. Reinstall the font with brew bundle --file=Brewfile if missing.
iTerm won't open a window / execvp failed: /usr/local/bin/zsh
An old profile hardcoded an Intel-Mac shell path. The committed profile is
already fixed — make sure install.sh --apply linked the current
iterm2/DynamicProfiles.json, then reopen iTerm.
brew bundle fails on one package
It continues past failures and reports at the end; install the named package
manually or remove its line from the Brewfile.
Undo the whole install
Symlinks live at the $HOME paths listed in install.sh's LINKS array; delete
them and restore from ~/.dotfiles-backup/<timestamp>/ if you had originals.
.zshrc shell entrypoint (plugins, keybindings, prompt, history)
.zsh_plugins.txt antidote plugin list
zsh/.zalias .zfunc aliases + functions (sourced by .zshrc)
zsh/.zexports env vars + $PATH
p10 powerlevel10k config (linked to ~/.p10k.zsh)
starship.toml starship config (alternate prompt)
nvim/ Neovim config (init.lua + lua/config + lua/plugins)
iterm2/ iTerm2 Dynamic Profile
fonts/ bundled fonts (Nerd Font comes from Brewfile)
Brewfile all Homebrew packages
install.sh symlink installer
.github/workflows/ CI (lint + smoke tests)
CI (.github/workflows/ci.yml) runs on every push:
shellcheck, zsh -n syntax, an isolated install.sh dry-run + idempotency
check, an interactive-load smoke test, and a headless Neovim plugin sync.
These predate the current setup. They're kept for reference and history but are not linked or used — safe to ignore, will be pruned eventually.
| Path | Was | Replaced by |
|---|---|---|
setup.py |
Prezto installer | install.sh |
zsh/zshrc, zpreztorc, zprofile |
Prezto runcoms | .zshrc |
zsh/prompt_*_setup, aaron.zsh-theme |
Prezto prompt themes | p10k / starship |
brew_list/brew_list.txt |
package list | Brewfile |
com.googlecode.iterm2.plist |
full iTerm prefs dump | iterm2/DynamicProfiles.json |
vim/.vimrc.legacy |
Vundle-based vim | nvim/ |
bash/, SublimeText/, bin/, .iterm2_shell_integration.bash |
bash-era tooling | — |