Skip to content

Latest commit

 

History

38 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

dotfiles

Personal configuration, tracked in one place and symlinked into the locations each tool expects.

Tools

Each tool has its own README with what it is, why it's used, and how the config is set up.

Tool What it's for Config
Zsh Shell + prompt, modular fast-startup setup config/zsh/, zshenv, zshrc, zprofile
Ghostty GPU terminal emulator (daily driver) config/ghostty/
kanata Keyboard remapper: Caps -> Esc / Hyper, app launchers config/kanata/
Neovim Main text editor plus a locally built macOS Finder launcher config/nvim/
Vim / IdeaVim Shared Vim config for real Vim + JetBrains IDEs config/vim/
Git Version control identity + line-ending / ignore policy config/git/
OpenCode Terminal AI coding agent config/opencode/
Gradle Global JVM / Android build tuning gradle/
SSH SSH client config (private keys stay untracked) ssh/
GnuPG GPG signing / encryption defaults (keys untracked) gnupg/
Agent instructions Shared AI-agent rules (Claude / Gemini / OpenCode / Codex) AGENTS.md

How it works

The real files live in this repo with plain, visible names (zshrc, not .zshrc). dotfiles.conf maps each source to its target under $HOME, and install.sh creates the symlinks. The installer also links every regular file under scripts/bin/ into $HOME/.local/bin.

Only individual files are ever symlinked. When a manifest entry points at a directory, every file beneath it is linked one by one and the directory tree at the target is created as real directories. That keeps app-generated junk (lock files, caches, state) out of this repo while still letting the app write next to the linked files.

Usage

git clone <repo> ~/.dotfiles
~/.dotfiles/install.sh

install.sh is idempotent:

  • links already pointing at the right place are left alone
  • manifest target collisions are moved into .backups/<timestamp>/ first
  • wrong executable symlinks are refreshed, while unrelated executable destination files are left untouched and reported as errors

Adding a new dotfile

  1. Move the file into this repo, mirroring its $HOME path but dropping the leading dot (e.g. ~/.config/foo/bar~/.dotfiles/config/foo/bar).
  2. Add a SOURCE TARGET line to dotfiles.conf.
  3. Run ./install.sh.

Layout

zshenv, zshrc, zprofile        → ~/.zshenv, ~/.zshrc, ~/.zprofile
config/zsh/                    → ~/.config/zsh/*.zsh (sourced by ~/.zshrc)
config/git/                    → ~/.config/git/config, ignore, attributes
config/ghostty/config          → ~/.config/ghostty/config
config/nvim/                   → ~/.config/nvim/ (lua config; lazy-lock.json stays app-managed)
config/vim/                    → ~/.config/vim/ (vimrc + colors) and ~/.config/ideavim/ideavimrc (mirrors the nvim setup)
config/opencode/               → ~/.config/opencode/opencode.jsonc, tui.json
gradle/gradle.properties       → ~/.gradle/gradle.properties
ssh/config                     → ~/.ssh/config
gnupg/gpg.conf, gpg-agent.conf → ~/.gnupg/gpg.conf, ~/.gnupg/gpg-agent.conf
AGENTS.md                      → ~/.claude/CLAUDE.md, ~/.gemini/GEMINI.md, ~/.config/opencode/AGENTS.md, ~/.codex/AGENTS.md, ~/AGENTS.md
scripts/bin/*                  → ~/.local/bin/*
config/nvim/launcher/*         → source for locally built ~/Applications/Nvim.app

Secrets

Only config is tracked, never key material. install.sh forces ~/.ssh and ~/.gnupg to 0700, and .gitignore refuses to stage private keys, keyrings, and GnuPG runtime state even if one is ever copied into the repo by accident.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages