Personal dotfiles managed with chezmoi.
- ZSH configuration (
.zshrc) with Oh My Zsh - Powerlevel10k theme configuration (
.p10k.zsh) - Ghostty terminal configuration (
.config/ghostty/config.ghostty) - Cross-platform Homebrew setup (works on macOS and Linux)
Powerlevel10k uses Nerd Font glyphs for its icons. Two easy options:
- Use Ghostty — it ships with JetBrains Mono Nerd Font bundled as the default font, so icons work with zero configuration. This repo also tracks a Ghostty config (theme, opacity, blur, and a global quick-terminal hotkey) that
chezmoi applyinstalls automatically. - Install a Nerd Font manually and set it as your terminal font:
brew install --cask font-meslo-lg-nerd-font
Important: The Oh My Zsh installer overwrites
~/.zshrc, so install Oh My Zsh and Powerlevel10k first, then apply chezmoi last.
brew install chezmoi tmux fzf thefuck direnv nvmsh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"When asked if you want to change your default shell, choose No if you're already using ZSH.
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10kchezmoi init https://github.com/QingqiShi/dotfiles.git
chezmoi diff # Preview changes
chezmoi applyThis overwrites the default ~/.zshrc that Oh My Zsh installed with the one from this repo, along with ~/.p10k.zsh.
On macOS, Ghostty also reads ~/Library/Application Support/com.mitchellh.ghostty/config.ghostty, and loads it after ~/.config/ghostty/config.ghostty. If a config is sitting there, it silently overrides the one this repo installs. Remove it so the tracked config wins:
rm -f ~/Library/Application\ Support/com.mitchellh.ghostty/config.ghosttyTo confirm which settings are actually live — here or any time Ghostty ignores a change you made:
/Applications/Ghostty.app/Contents/MacOS/ghostty +show-config --default=falseEdit the config with chezmoi edit ~/.config/ghostty/config.ghostty, not through Ghostty's own Cmd+,, which writes to the untracked Application Support path.
exec zshOr simply open a new terminal window.
Quick reference for the day-to-day features installed by these dotfiles. Forgot what something does? Start here.
A fast, information-rich Zsh prompt showing the current directory, git branch and dirty state, exit code and duration of the previous command, and Node version (in JS projects). Two comfort features worth knowing about:
- Instant prompt — the prompt renders from a cache before
.zshrcfinishes loading, so cold shells feel instantaneous. - Transient prompt — previous prompts collapse to a single line in scrollback so history stays tidy.
Reconfigure with p10k configure (overwrites ~/.p10k.zsh — remember to run chezmoi re-add ~/.p10k.zsh afterwards to save it back to the repo).
The single biggest productivity boost in the whole setup. Key bindings are wired up automatically via the OMZ fzf plugin — no extra config needed.
| Shortcut | What it does |
|---|---|
| Ctrl-R | Fuzzy-search shell history (the killer feature — never history | grep again) |
| Ctrl-T | Fuzzy-find a file under the current directory and paste its path onto the command line |
| Alt-C | Fuzzy-cd into a subdirectory |
**<Tab> |
Fuzzy completion for any command: vim **<tab>, cd **<tab>, kill **<tab> (pid picker), ssh **<tab>, etc. |
The OMZ git plugin ships ~150 aliases. The ones worth memorizing:
| Alias | Expands to |
|---|---|
gst |
git status |
gco <branch> |
git checkout <branch> |
gcb <branch> |
git checkout -b <branch> (create + switch) |
gc |
git commit -v (opens editor) |
gcmsg "msg" |
git commit -m "msg" |
ga <file> / gaa |
git add <file> / git add --all |
gd / gds |
git diff / git diff --staged |
gp / gl |
git push / git pull |
glog |
git log --oneline --decorate --graph |
gb / gbd <name> |
git branch / git branch -d <name> |
grb / grbi |
git rebase / git rebase -i |
gsta / gstp |
git stash / git stash pop |
Full list: OMZ git plugin reference.
Drop a .envrc file in a project root, run direnv allow once, and its contents auto-load when you cd in and auto-unload when you cd out. Keeps secrets out of .zshrc and scopes env vars to the projects that need them.
# in some-project/.envrc
export OPENAI_API_KEY="sk-..."
export DATABASE_URL="postgres://localhost/myapp"$ cd some-project
direnv: loading ~/some-project/.envrc
direnv: export +OPENAI_API_KEY +DATABASE_URL| Command | What it does |
|---|---|
nvm install 22 |
Install Node 22 |
nvm use 22 |
Switch the current shell to Node 22 |
nvm alias default 22 |
Default Node version for new shells |
nvm ls |
List installed versions |
nvm current |
Show active version |
Lazy-loading note: nvm is not sourced when your shell starts — it's stubbed for nvm, node, npm, npx, pnpm, yarn, and corepack, and only actually loads the first time you call one of those. Expect a ~200-500ms one-time pause on first use in a new shell, in exchange for dramatically faster shell startup.
Auto-switching: cd into a directory containing an .nvmrc and the shell switches to that Node version automatically, reverting to your default on the way out. Projects pinned to an older Node "just work" without a manual nvm use; install the version once with nvm install if it's missing.
Mistyped the last command? Type fuck and hit Enter. It reruns the previous command with the most likely fix, asking for confirmation first.
$ gti status
zsh: command not found: gti
$ fuck
git status [enter/↑/↓/ctrl+c]The OMZ tmux plugin adds convenience aliases:
| Alias | Expands to |
|---|---|
ta |
tmux attach (attach to the last session) |
ts <name> |
tmux new-session -s <name> |
tl |
tmux list-sessions |
tkss <name> |
Kill a specific session |
Once inside tmux, the prefix key is Ctrl-b:
| Keys | Action |
|---|---|
Ctrl-b c |
New window |
Ctrl-b n / p |
Next / previous window |
Ctrl-b % / " |
Split pane vertically / horizontally |
Ctrl-b <arrow> |
Move focus between panes |
Ctrl-b d |
Detach (session keeps running in the background) |
Ctrl-b [ |
Enter copy / scroll mode (q to exit) |
- `Ctrl+`` (global) — toggle the drop-down quick terminal from anywhere in macOS. Requires Accessibility permission — see Troubleshooting.
Shift+Enter— in TUI apps like Claude Code, inserts a literal newline without submitting the current input.Alt+Backspace— delete the previous word on the command line.- Appearance — Aura theme, 90% opacity with background blur.
- Config location —
~/.config/ghostty/config.ghostty. Ghostty prefers~/Library/Application Support/com.mitchellh.ghostty/config.ghosttyif that exists, so keep it deleted — see step 5.
Chezmoi is configured to automatically commit and push changes.
chezmoi edit ~/.zshrcchezmoi re-add ~/.zshrcThis will automatically commit and push to the repository.
chezmoi updateIf you need to manually work with the repository:
chezmoi cd # Enter chezmoi source directory
git status # Check status
git add . # Stage changes
git commit -m "" # Commit
git push # Push to GitHub
exit # Return to previous directoryThe .zshrc is configured to work across platforms. It checks for Homebrew in:
/opt/homebrew/bin/brew(Apple Silicon Mac)/usr/local/bin/brew(Intel Mac)/home/linuxbrew/.linuxbrew/bin/brew(Linux)
If you see plugin errors on shell startup, ensure you've completed step 1 — it installs direnv, nvm, fzf, thefuck, and tmux, which back the Oh My Zsh plugins enabled in .zshrc.
If Powerlevel10k theme isn't found, ensure you've run step 3 and that Oh My Zsh is installed.
Your terminal font isn't a Nerd Font. See the Nerd Font section above.
The Ghostty config registers a global (system-wide) hotkey to toggle its quick terminal. On macOS, Ghostty needs Accessibility permission to capture global hotkeys. On first launch after applying dotfiles, macOS should prompt you — grant permission in System Settings → Privacy & Security → Accessibility. If it doesn't prompt, toggle Ghostty's entry off and on again there.
Print what Ghostty actually loaded:
/Applications/Ghostty.app/Contents/MacOS/ghostty +show-config --default=falseIf the values don't match ~/.config/ghostty/config.ghostty, a second config is winning at ~/Library/Application Support/com.mitchellh.ghostty/config.ghostty. Delete it — see step 5. A running Ghostty keeps its old config in memory, so reload with Cmd+Shift+, or restart it afterwards.