My macOS development environment on an M4 Max MacBook, managed with GNU Stow and nix-darwin.
dotfiles/
├── aerospace/ # AeroSpace tiling WM (Stow → ~/.config/aerospace/)
│ └── aerospace.toml
├── gh-dash/ # GitHub dashboard (Stow → ~/.config/gh-dash/)
│ └── config.yml
├── ghostty/ # Ghostty terminal (Stow → ~/.config/ghostty/)
│ └── config
├── nushell/ # Nushell config (Stow → ~/.config/nushell/)
│ ├── config.nu
│ └── env.nu
├── nvim/ # Neovim config (Stow → ~/.config/nvim/)
│ └── ...
├── television/ # Television fuzzy finder (Stow → ~/.config/television/)
│ └── config.toml
├── tmux/ # Tmux config (Stow → ~/.config/tmux/)
│ ├── tmux.conf
│ └── tmux.reset.conf
├── zshrc/ # Zsh config (Stow → ~/.zshrc)
│ └── .zshrc
├── nix-darwin/ # nix-darwin system config (NOT managed by Stow)
│ ├── flake.nix
│ ├── configuration.nix
│ └── home.nix
├── .stowrc
├── .gitignore
└── setup.sh
curl -L https://nixos.org/nix/install | shClose and reopen your terminal, then enable flakes:
mkdir -p ~/.config/nix
echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.confgit clone git@github.com:gargimahale/dotfiles.git ~/dotfilescd ~/dotfiles/nix-darwin
nix --extra-experimental-features "nix-command flakes" run nix-darwin -- switch --flake . --impureAfter the first build, rebuild with:
darwin-rebuild switch --flake . --impureSome packages fail to build through nix. Install via brew:
/opt/homebrew/bin/brew install direnv misegit clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpmThen open tmux and press Ctrl+A then I (capital I) to install plugins.
gh auth login
gh extension install dlvhdr/gh-dashbrew install televisioncd ~/dotfiles
./setup.shopen /Applications/AeroSpace.appGrant accessibility permissions at System Settings → Privacy & Security → Accessibility.
The .stowrc configures defaults:
--target=~/.config
--ignore=.stowrc
--ignore=DS_Store
--ignore=atuin/*
--ignore=.git
--ignore=.gitignore
Most packages target ~/.config via .stowrc. Zsh targets ~ directly in setup.sh:
stow -t ~ zshrc
stow ghostty
stow nushell
stow aerospace
stow tmux
stow gh-dash
stow televisionSystem config in nix-darwin/ manages system packages, flakes, zsh as default shell, and macOS defaults.
System packages: neovim, git, bat, eza, fd, fzf, ripgrep, zoxide, starship, stow, tree, nushell, carapace, atuin, aerospace.
Home-manager reads ../zshrc/.zshrc via builtins.readFile so zsh config has a single source of truth. The --impure flag is required for this.
cd ~/dotfiles/nix-darwin
darwin-rebuild switch --flake . --impureAeroSpace is a tiling window manager. Windows automatically arrange into tiles — no dragging.
| Shortcut | Action |
|---|---|
| Alt + H | Focus left |
| Alt + J | Focus down |
| Alt + K | Focus up |
| Alt + L | Focus right |
| Shortcut | Action |
|---|---|
| Alt + Shift + H | Move window left |
| Alt + Shift + J | Move window down |
| Alt + Shift + K | Move window up |
| Alt + Shift + L | Move window right |
| Shortcut | Action |
|---|---|
| Alt + Shift + - | Shrink by 50px |
| Alt + Shift + = | Grow by 50px |
| Shortcut | Action |
|---|---|
| Alt + 1/2/3/4 | Switch to workspace |
| Alt + Shift + 1/2/3/4 | Move window to workspace |
| Alt + Tab | Toggle last two workspaces |
| Shortcut | Action |
|---|---|
| Alt + Ctrl + Shift + F | Toggle fullscreen |
| Alt + Ctrl + F | Toggle floating/tiling |
| Alt + / | Toggle horizontal/vertical tiles |
| Alt + , | Toggle accordion layout |
| Shortcut | App |
|---|---|
| Alt + G | Ghostty |
| Alt + O | Obsidian |
| Alt + D | Discord |
| Alt + F | Finder |
| Shortcut | Action |
|---|---|
| Alt + Shift + ; | Enter service mode |
| R (in service mode) | Reset layout |
| F (in service mode) | Toggle float/tile |
| Backspace (in service mode) | Close all windows except current |
| Esc (in service mode) | Reload config and exit |
| Shortcut | Action |
|---|---|
| Alt + Shift + ← | Join with left |
| Alt + Shift + ↓ | Join with down |
| Alt + Shift + ↑ | Join with up |
| Alt + Shift + → | Join with right |
Tmux is a terminal multiplexer. Prefix is Ctrl+A (not the default Ctrl+B).
| Shortcut | Action |
|---|---|
| Ctrl+A, v | Split vertical |
| Ctrl+A, s | Split horizontal |
| Ctrl+A, h/j/k/l | Move between panes (vim-style) |
| Ctrl+A, c | Kill pane |
| Ctrl+A, z | Zoom/unzoom pane |
| Ctrl+A, , | Resize pane left |
| Ctrl+A, . | Resize pane right |
| Ctrl+A, - | Resize pane down |
| Ctrl+A, = | Resize pane up |
| Shortcut | Action |
|---|---|
| Ctrl+A, Ctrl+C | New window |
| Ctrl+A, H | Previous window |
| Ctrl+A, L | Next window |
| Ctrl+A, Ctrl+A | Last window |
| Ctrl+A, r | Rename window |
| Shortcut | Action |
|---|---|
| Ctrl+A, o | Session manager (sessionx) |
| Ctrl+A, S | Choose session |
| Ctrl+A, Ctrl+D | Detach |
| Shortcut | Action |
|---|---|
| Ctrl+A, p | Floating pane (floax) |
| Ctrl+A, I | Install plugins (TPM) |
| Ctrl+A, R | Reload config |
| Ctrl+A, K | Clear screen |
| Plugin | Purpose |
|---|---|
| tpm | Plugin manager |
| tmux-sensible | Sensible defaults |
| tmux-yank | Copy to system clipboard |
| tmux-resurrect | Save/restore sessions |
| tmux-continuum | Auto-save sessions |
| tmux-fzf | Fuzzy finder integration |
| tmux-fzf-url | Open URLs from terminal |
| catppuccin-tmux | Theme |
| tmux-sessionx | Session manager |
| tmux-floax | Floating panes |
Television is a fast fuzzy finder with "channels" for searching different data sources.
tv # Search files (default)
tv text # Search file contents
tv git-repos # Find git repositories
tv git-log # Browse git history
tv git-branch # Switch branches
tv git-diff # Browse diffs
tv env # Search environment variables
tv dirs # Search directories
tv docker-images # Search docker imagesTerminal dashboard for GitHub PRs, issues, and notifications.
gh dash| Key | Action |
|---|---|
| ? | Help |
| / | Search |
| j/k | Move up/down |
| Enter | Open in browser |
| Tab | Switch sections (PRs/Issues/Notifications) |
| Ctrl+D | Preview diff |
| c | Comment |
| a | Approve PR |
| m | Merge PR |
| Ctrl+B | Open in browser |
| Section | Filter |
|---|---|
| My Pull Requests | Open PRs authored by you |
| Needs My Review | PRs requesting your review |
| Involved | PRs you're involved in |
| My Issues | Issues you created |
| Assigned | Issues assigned to you |
| Notifications | All, review requested, mentioned, assigned |
Nushell is a structured data shell. Everything outputs tables instead of plain text.
Useful commands to try:
ls | sort-by size # sort files by size
sys mem # memory usage as structured data
ps | where cpu > 5 # processes using more than 5% CPU
open file.json # parse JSON into a table
| Alias | Command |
|---|---|
| l | ls --all |
| ll | ls -l |
| lt | eza tree view |
| c | clear |
| v | nvim |
| cx [dir] | cd + list |
| ff | fuzzy-find AeroSpace windows |
| as | aerospace |
| Alias | Command |
|---|---|
| .. / ... / .... | cd up directories |
| cat | bat |
| la | tree |
| l | eza -l --icons --git -a |
| v | nvim |
| cl | clear |
| cx [dir] | cd + list |
| fcd | fuzzy-find directory |
| f | fuzzy-find file → clipboard |
| fv | fuzzy-find file → nvim |
| z [keyword] | zoxide smart cd |
GPU-accelerated terminal with Monokai Remastered theme, JetBrains Mono font, and translucent background.
| Setting | Value |
|---|---|
| Theme | Monokai Remastered |
| Font | JetBrains Mono, 15pt |
| Background | #031219, 90% opacity |
| Blur | 20px radius |
| Cursor | Block, blinking |
| Option key | Left Alt sends Alt (for AeroSpace) |
| Tool | Purpose |
|---|---|
| Ghostty | GPU-accelerated terminal (Monokai Remastered, JetBrains Mono) |
| Neovim | Editor (lazy.nvim, LSP via vim.lsp.config, treesitter) |
| Nushell | Structured data shell (vi mode, starship prompt) |
| AeroSpace | Tiling window manager |
| Tmux | Terminal multiplexer (catppuccin, sessionx, floax) |
| gh-dash | GitHub PR/issue dashboard in terminal |
| Television | Fast fuzzy finder with channels |
| Starship | Cross-shell prompt |
| Zoxide | Smart directory jumping (z command) |
| Carapace | Universal tab completions (bridges zsh/fish/bash) |
| Atuin | Shell history search (Ctrl+R) |
| Mise | Tool version manager (replaces nvm/pyenv/rbenv) |
| Direnv | Per-directory environment variables |
| GNU Stow | Dotfile symlink manager |
| Bat | cat with syntax highlighting |
| Eza | ls with icons and git status |
| Fd | Fast find alternative |
| Fzf | Fuzzy finder |
| Ripgrep | Fast grep alternative |
sudo launchctl load /Library/LaunchDaemons/org.nixos.nix-daemon.plistnix-darwin takes over PATH. Ensure /opt/homebrew/bin is in your .zshrc, or use /opt/homebrew/bin/brew directly.
sudo mv /etc/bashrc /etc/bashrc.before-nix-darwin
sudo mv /etc/zshrc /etc/zshrc.before-nix-darwinAdd to configuration.nix:
system.primaryUser = "gargimahale";sudo darwin-rebuild switch causes $HOME to resolve to /var/root. Run without sudo — it prompts for your password when needed.
Some system.defaults settings only apply after a restart. If keyboard shortcuts break after a rebuild, reboot first.
Install via brew instead:
/opt/homebrew/bin/brew install direnv miseMake sure AeroSpace is running (open /Applications/AeroSpace.app) and has accessibility permissions enabled in System Settings.
Ghostty's macos-option-as-alt = left may intercept Alt before AeroSpace gets it. If AeroSpace keybindings don't work inside Ghostty, this is why. Test keybindings from another app first.
If Stow says "cannot stow over existing target", either remove the existing file or use --adopt:
rm ~/.config/television/config.toml
stow television
# or
stow --adopt televisionInstall TPM first, then press Ctrl+A, I inside tmux:
git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpmIf you see require('lspconfig') is deprecated, update lsp.lua to use vim.lsp.config() and vim.lsp.enable() instead. See the refactored lsp.lua in nvim/lua/ferb/lazy/lsp.lua.