macOS developer configuration files following the XDG Base Directory specification.
After running install.sh, ~/.config becomes a symlink pointing to ~/dotfiles/.config:
~/.config → ~/dotfiles/.config (symlink)
This means you only ever edit files in one place: ~/.config/ (or equivalently ~/dotfiles/.config/ — they are the same directory). Any edit is automatically inside the git repo.
This dotfiles repo uses git submodules for two things:
- Neovim (
aladinoster/config.nvim) — also used independently on other machines - TPM (
tmux-plugins/tpm) — pinned at a known-good commit, installed alongside the rest of the dotfiles
Everything else lives directly in this repo.
| Config | Repo | Where to edit |
|---|---|---|
| tmux, zsh, git, lazygit, etc. | aladinoster/dotfiles |
~/.config/<tool>/ |
| Neovim | aladinoster/config.nvim |
~/.config/nvim/ |
| TPM | tmux-plugins/tpm |
submodule, don't edit directly |
Non-nvim configs (tmux, zsh, brew.sh, etc.):
cd ~/dotfiles
git add -A
git commit -m "update tmux config"
git pushNeovim config — two steps (push nvim, then update the pointer in dotfiles):
# Step 1: push nvim changes to config.nvim
cd ~/.config/nvim
git add -A && git commit -m "add plugin xyz" && git push
# Step 2: record the new nvim commit in dotfiles
cd ~/dotfiles
git add .config/nvim
git commit -m "chore: bump nvim submodule"
git pushOr use the nvim-push shell function (defined in config.d/tools.zsh) to do both in one shot:
nvim-push "add plugin xyz"If you made nvim changes on your other laptop and pushed them to config.nvim:
# Pull the latest nvim commits into this machine's submodule
cd ~/dotfiles
git submodule update --remote .config/nvim
# Record the updated pointer
git add .config/nvim
git commit -m "chore: sync nvim from other machine"
git pushcd ~/dotfiles
git pull
git submodule update --init --recursive # also pulls nvim + tpmXDG-compliant tool (writes to ~/.config/newtool/) — nothing to do, it's already inside the repo. Just start tracking it when ready:
# Ignore it (app-generated, don't want to track):
echo "newtool/" >> ~/dotfiles/.config/.gitignore
# Track it:
cd ~/dotfiles
git add .config/newtool/
git commit -m "feat: add newtool config"
git push origin HEAD:masterHome-directory dotfile (must live at ~/.something) — put the file in ~/dotfiles/, add a symlink line to install.sh, then link it manually once:
# 1. Move the file into dotfiles
mv ~/.sometoolrc ~/dotfiles/.sometoolrc
# 2. Add to install.sh (under "Home dotfiles" section):
# ln -sf "$DOTFILES/.sometoolrc" "$HOME/.sometoolrc"
# 3. Create the symlink now (don't re-run full install.sh):
ln -sf ~/dotfiles/.sometoolrc ~/.sometoolrc
# 4. Commit
cd ~/dotfiles
git add .sometoolrc install.sh
git commit -m "feat: track sometoolrc"
git push origin HEAD:master| Tool | Location | Description |
|---|---|---|
| Zsh | .config/zsh/ |
Oh My Zsh + Powerlevel10k, modular config.d |
| Tmux | .config/tmux/ |
TPM plugins, Catppuccin theme, vim-tmux-navigator |
| Neovim | .config/nvim/ |
Lazy.nvim, LSP, DAP, Telescope, Harpoon, REPL (slime/iron) |
| Git | .config/git/ |
Aliases, LFS, nvim editor |
| Lazygit | .config/lazygit/ |
TUI Git client config |
| Marimo | .config/marimo/ |
Reactive Python notebook config |
| Htop | .config/htop/ |
Process viewer config |
| GH CLI | .config/gh/ |
GitHub CLI config |
-
Install Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Install Oh My Zsh:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" -
Install Rust (optional, needed for cargo):
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# 1. Clone the repository
git clone https://github.com/aladinoster/dotfiles.git ~/dotfiles
cd ~/dotfiles
# 2. Install packages
chmod +x brew.sh && ./brew.sh
# 3. Create symlinks
chmod +x install.sh && ./install.sh
# 4. Restart your terminal
exec zshTPM is included as a git submodule at .config/tmux/plugins/tpm and is initialized automatically by install.sh via git submodule update --init --recursive. No manual clone needed.
tmux 3.1+ loads ~/.config/tmux/tmux.conf natively (XDG), so no ~/.tmux.conf is required.
After running install.sh, open tmux and install plugins:
<prefix> + I # Install plugins
<prefix> + U # Update pluginsPlugins included:
tmux-sensible— sensible defaultstmux-resurrect+tmux-continuum— session persistencetmux-yank— clipboard integrationtmux-sessionx— fuzzy session picker (<prefix> + O)vim-tmux-navigator— seamless pane/split switching with Neovimcatppuccin/tmux— Mocha theme
Neovim config uses Lazy.nvim for plugin management. It auto-installs on first run.
See .config/nvim/README.md for full keybindings reference.
Key plugins: Telescope, Treesitter, LSP (Mason), DAP, Harpoon, Oil, Slime/Iron REPL, Noice, TokyoNight, Obsidian, Neorg.
.config/zsh/
├── .zshrc # Main config (Oh My Zsh, plugins, history)
├── .p10k.zsh # Powerlevel10k prompt config
└── config.d/ # Modular configs (auto-sourced)
├── exports.zsh # PATH, EDITOR, language managers (pyenv, cargo, bun)
├── nvm.zsh # Node Version Manager
├── tools.zsh # Aliases, fzf config, helper functions
└── secrets.zsh # Private exports (NOT tracked in git)
.zshenv (at $HOME) sets ZDOTDIR=$HOME/.config/zsh and XDG_CONFIG_HOME.
dotfiles/
├── .zshenv # Sets ZDOTDIR and XDG_CONFIG_HOME
├── .aliases # Git, docker shortcuts
├── brew.sh # Package installation
├── install.sh # Symlink setup
└── .config/
├── git/
├── nvim/ ← submodule (aladinoster/config.nvim)
├── tmux/
│ ├── tmux.conf
│ └── plugins/
│ └── tpm/ ← submodule (tmux-plugins/tpm)
├── zsh/
├── lazygit/
├── marimo/
├── htop/
└── gh/