Personal configuration files for my macOS development environment, centered on Neovim, Zsh, and Ghostty.
- macOS
- No other prerequisites —
setup.shinstalls Homebrew and everything else fromBrewfile.
git clone https://github.com/ronload/dotfiles.git ~/dotfiles
cd ~/dotfiles
./setup.shsetup.sh installs Homebrew, Rust, and every package in Brewfile, then hands off to install.sh to symlink configs, clone fzf-git.sh, and sync Neovim plugins. Each step is idempotent and safe to re-run.
- nvim: Neovim with lazy.nvim and TokyoNight Moon
- zsh: Zsh shell (zshrc, zprofile, zshenv, aliases, prompt, abbreviations)
- ghostty: Ghostty terminal
- git: Git global config (with conditional work identity include)
- gh: GitHub CLI
- fastfetch: System info with a custom colored-bar module
- karabiner: Karabiner-Elements keyboard customization
- yazi: Terminal file manager
- Brewfile: Homebrew package manifest
Linting and formatting are driven by just. The justfile is the single source of truth — GitHub Actions invoke the same recipes on every push and pull request.
just # list all recipes
just ci # run every linter and formatter check
just lint # run all linters (lua, shell, zsh)
just format # run all formatter checks (lua, shell)
just lint-lua # luacheck on tracked Lua files
just lint-shell # shellcheck on tracked shell scripts
just lint-zsh # zsh -n syntax check on zsh/*
just format-lua # stylua --check
just format-shell # shfmt -i 2 -ci -d
just test # run all tests
just test-install # verify install.sh reproduces every declared symlinkAll linter recipes operate on git ls-files, so untracked files are skipped. Zsh files are validated by zsh -n rather than shellcheck, which does not support zsh.
install.sh linking is verified on every PR (just test-install, via install-test.yml): runs install.sh against a disposable copy of the repo and a sandbox $HOME, then asserts every declared symlink exists, points at the right target, is not broken, and that a second run re-links nothing. Fully offline and isolated; touches neither the real working tree nor the real home directory.
Two details make reproduction location-independent and Karabiner-safe:
- Several configs reference the repo by the absolute path
~/dotfiles(tmux, git, ghostty, fastfetch, zsh), and those tools cannot resolve the path dynamically.install.shtherefore ensures~/dotfilespoints at the repo, so it can be cloned anywhere; cloning to~/dotfilesdirectly needs no extra link. An existing real~/dotfilesthat is not this repo is left untouched and the install aborts. ~/.config/karabineris symlinked as a whole directory rather than justkarabiner.json, because Karabiner-Elements replaces a symlinked config file on save (per its docs). A pre-existing real config directory is backed up to.bakbefore linking.
git/gitconfig conditionally includes a work identity for repos under git@github.com:prinsur/**:
[includeIf "hasconfig:remote.*.url:git@github.com:prinsur/**"]
path = ~/.gitconfig-prinsurThis override file is not tracked. Create it manually on each machine:
cat > ~/.gitconfig-prinsur <<'EOF'
[user]
email = your-work-email@example.com
EOFWithout it, commits to prinsur/* repos fall back to the global identity.
Released under the MIT License. See LICENSE for details.
