Personal configuration files for zsh, tmux, neovim, ghostty, git and much more.
Quick Start · How it works · Features · Themes · Keybindings · Docs
Prerequisites: macOS or Linux. On a fresh macOS, run xcode-select --install first.
git clone https://github.com/undont/dotfiles.git ~/dotfiles
cd ~/dotfiles
./install.sh # full install (default)| Preset | Components | Use case |
|---|---|---|
--minimal |
zsh, tmux | servers, remote machines, SSH |
--core |
+ nvim, ghostty, AI/CLI tools, launchers | Linux desktop, cross-platform dev |
--full |
+ Hammerspoon, Karabiner, Raycast, music-presence | macOS power user (default) |
The installer backs up existing configs, installs Homebrew packages filtered by preset, creates symlinks, sets up plugin managers, and runs a health check. Your preset is saved so dotfiles update remembers it.
Other flags: --skip-brew, --skip-backup, --check-only. See the Installation Guide for a walkthrough of each step.
The setup is layered: a shared base lives in this repo and gets symlinked into place, and tools that support it (tmux, ghostty, nvim, lazygit, gh-dash, hammerspoon) load a local.* file on top that dotfiles update never touches. Clone the repo, keep your tweaks in the local files, and run dotfiles update to pull upstream changes; your overrides survive. Fork it if you really want to make it your own or take the base in a different direction.
Version-gated scripts in scripts/migrations/ run automatically during dotfiles update to handle changes the normal installer can't. They're idempotent and only run once per version range.
Built around staying on the keyboard: ` as the tmux prefix, fzf pickers everywhere, vim motions under space as <leader> in nvim, and zsh aliases for anything frequent enough to warrant one. Used daily across personal and work machines on macOS and Linux.
Configured as a clean input layer rather than a productivity surface: keybind remappings emit consistent escape sequences across macOS and Linux (via a {{PLATFORM_MOD}} template), so the same tmux and nvim keybinds work identically on both platforms. The colour scheme follows the active dotfiles theme, and ~/.config/ghostty/local is loaded last so fonts and personal tweaks survive updates.
Modular config based on kickstart.nvim with lazy.nvim, Treesitter, and Mason-managed language servers. Startup is roughly 100ms.
- LSP for TypeScript, Go, Python, Lua, Rust, Zig, C#/.NET (Roslyn), C/C++/Objective-C, Swift, ESLint, Bash, CSS/Tailwind, HTML and YAML, with formatting and linting
- Debugging (nvim-dap): launch, attach and test debugging for Go, TypeScript/JavaScript (node and the browser), Lua (including nvim plugin code), Rust, Zig, Python, .NET and the C family
- SonarLint as a second LSP client, with connected mode and per-project rule overrides. See docs/SONARLINT.md
- Diffs and PR review through differ.nvim (my own plugin): side-by-side diffs, file history, staging, GitHub PR review, merge conflict resolution, and diff-by-ticket, all through one renderer
- Build picker auto-detects Go, TypeScript, .NET and Makefile projects and runs the build into the quickfix list
- Tests via Neotest (Go, Vitest/Bun, Jest/React Native, pytest), with .NET handled by easy-dotnet's own runner
- Binary object viewer: opening a
.o,.a,.dylibor.sorenders demangled symbols, disassembly and a hex dump instead of raw bytes - Self-contained colourschemes with no plugin dependencies, so generated themes drop in as plain Lua files
~/.config/nvim/local.lualoads before plugin specs, sovim.g.*is visible to them
` as the prefix, vim-style navigation between panes and windows, and a searchable key cheatsheet (` ?) if you forget anything.
- Session save and restore with resurrect + continuum, extended to split the combined save into per-session backups, so one session can be restored without bringing back everything else
- fzf pickers everywhere: sessions, windows, running nvim instances, AI agent instances, themes, and URLs from scrollback
- Multi-agent alerts show coloured indicators when Claude, OpenCode, Copilot or Codex need attention, clearing when you switch to the session. The Claude and OpenCode switchers also show live per-instance state and how long it has been waiting. See docs/AGENT-HOOKS.md
- Process list is one fzf switcher over everything you're watching: live commands with elapsed time plus finished ✓/✗ rows, with jump, stop, clear and rerun
- Undo restores the most recently closed pane or window with directory, scrollback and layout intact
- Session launchers are TOML files (
launchers/*.toml, plus your own in~/.config/dotfiles/launchers) that build a session in tmux or Rex. They coverdev,github,btop,docker,dotfilesandconfig, with a wizard to scaffold new ones, orsin the launcher picker to save the current session as one. Also reachable from a plain shell with Ctrl+O
- Powerlevel10k prompt with instant prompt and git status
- Performance: lazy-loaded completions, fnm over nvm, and cached eval for direnv and fzf, with median startup benchmarked in CI on every push (the job fails above 125ms)
- carapace as the completion bridge, so modern completion specs work without per-tool wrangling
- zoxide for a
cdthat learns the directories you actually use - Clipboard:
<cmd> | clipcopies and bareclippastes, on macOS and Linux alike, following the live display server and falling back to OSC 52 so it works headless and over SSH - Man pages open in nvim, so search,
Kand yank behave as in any other buffer - Git, navigation and editing aliases throughout; run
dot aliasesfor the full list
dotfiles update # pull the branch's upstream, re-running only changed steps
dotfiles status # version, preset, theme, sync status, and local changes
dotfiles health # full health check (symlinks, plugins, env vars)
dotfiles links # show all managed symlinks and their status
dotfiles theme # list, switch, or generate themes
dotfiles export # export your local layer to a private repo
dotfiles import # import your local layer from a private repo
dotfiles local # manage the private local-layer repo
dotfiles aliases # browse all shell aliases and shortcuts
dotfiles notes # browse the changelog in a pager
dotfiles version # current version
dotfiles edit nvim # open dotfiles, or a local config such as nvim's local.lua, in $EDITOR
dotfiles cd tmux # cd into dotfiles, or a target's directorydot is a shorthand for dotfiles. Both have full tab completion.
From within tmux, ` t opens an fzf picker over the hand-crafted set and Ghostty's themes; selecting one re-skins tmux, ghostty, neovim and fzf with no restart; gh-dash and yazi pick up the new theme on their next launch.
Two sources feed the picker:
- 15 hand-crafted themes with tuned palettes, all checked against WCAG 2.1 contrast ratios
- ~460 Ghostty themes generatable on the fly, deriving semantic roles from a Ghostty palette and correcting for contrast
dotfiles theme # list available themes
dotfiles theme switch dracula # switch by name
dotfiles theme switch random # switch to a random dark theme
dotfiles theme generate "Catppuccin Latte" # generate from a Ghostty paletteThemes are pure colour palettes. Anything else you want to customise goes in the per-tool local.* files, which are never touched by dotfiles update.
See docs/THEME-SYSTEM.md for the architecture, the generator, and statusline integration for AI CLI agents. See docs/LOCAL-LAYER.md for the override files and syncing them between machines.
Three flavours selected at install time (--minimal, --core, --full), filtered from a single Brewfile via preset markers. Browse it directly for the full list.
My own tools installed by it (gh-bench as a gh extension, the rest from the Brewfile):
| Tool | What it does |
|---|---|
| supplyscan | Go CLI / MCP that scans JS-ecosystem projects for vulnerabilities and supply-chain attacks |
| jiru | Bubble Tea TUI for managing Jira issues and Confluence pages |
| gh-bench | gh CLI extension for benchmarking GitHub Actions and tracking failures |
Homebrew requires explicit trust for non-official taps. The taps these tools come from are trusted during install; to add your own, approve it once with brew trust --tap <user/repo>.
The full preset adds macOS-only pieces (Hammerspoon window management, Karabiner remapping, Raycast) and Linux picks up keyd as the Karabiner equivalent.
| Action | Keybinding |
|---|---|
| Tmux prefix | ` |
| Tmux cheatsheet | ` ? |
| Session switcher | ` s |
| Launcher picker | ` p |
| Process list | ` Shift+P |
| Theme picker | ` t |
| Undo pane/window | Opt/Alt+u |
| Nvim leader | Space |
| Nvim cheatsheet | Space ? |
| History search | Ctrl+R |
| Directory history | Opt/Alt+A |
The full sets are all available in-product, and stay current because they're generated from the config rather than transcribed:
- Tmux:
` ?opens the searchable cheatsheet - Neovim: Space ? opens the searchable cheatsheet
- Zsh:
dot aliasesbrowses every alias, function and binding
./scripts/install/uninstall.sh # remove symlinks only
./scripts/install/uninstall.sh --restore-backup # restore original configs
./scripts/install/uninstall.sh --restore-backup --remove-brew-packages # full uninstall- Agent Hooks: setup guide for agent alert hooks (Claude Code, OpenCode, Codex, Copilot)
- Command Exit Alerts: auto ✓/✗ alerts when commands finish in other windows
- Installation Guide: detailed walkthrough of each installation step
- Local Layer: override files, and syncing them between your machines
- Secrets: API keys read on demand rather than exported to every shell
- SonarLint: SonarQube/SonarCloud diagnostics in Neovim
- Theme System: how themes work, the Ghostty theme generator, and WCAG contrast checks
- Troubleshooting: common issues and solutions