Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# dotfiles

David's personal dotfiles. Clean, minimal, actually deployable.

## What's in here

| File | Description |
|------|-------------|
| `zshrc` | Zsh config — prompt, history, aliases, tool integrations |
| `gitconfig` | Git aliases, modern defaults, color config |
| `gitignore` | Global git ignores |
| `tmux.conf` | Tmux config — Tokyo Night theme, sane bindings |
| `tmux.mac.conf` | macOS-specific tmux tweaks (pbcopy) |
| `ghostty.config` | Ghostty terminal config — Tokyo Night, Monaspace font |
| `nvim/` | Neovim config (LazyVim-based, Ruby + Copilot extras) |

## Approach

No dotfiles framework. Just a git repo + symlinks.

**Why?**
- v1–v3 used increasingly complex module systems. Too much ceremony.
- v4 proved that a flat file of configs works fine.
- v5 adds neovim and a simple install script — nothing more.

## Install

```bash
git clone https://github.com/davidstosik/dotfiles ~/.dotfiles
cd ~/.dotfiles
./install.sh
```

The install script:
1. Symlinks config files into `$HOME` and `$HOME/.config/`
2. Installs TPM (tmux plugin manager) if missing
3. Prints next steps for Neovim and tools

## Prerequisites

- macOS with [Homebrew](https://brew.sh)
- Install tools you actually use:

```bash
brew install git tmux neovim mise gh the_silver_searcher fzf
brew install --cask ghostty
```

For 1Password CLI (used for shell completion in zshrc):
```bash
brew install 1password-cli
```

For NVM (Node version manager, used in zshrc):
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
```

## Machine-local overrides

For machine-specific settings, create files that won't be committed:

- `~/.gitconfig.local` — included by gitconfig (name, email, work stuff)
- `~/.zshrc.local` — sourced at end of zshrc if it exists

Example `~/.gitconfig.local`:
```ini
[user]
name = David Stosik
email = work@example.com
```

## VPN fix

The `vpn-fix` function in zshrc fixes routing when there's a subnet conflict
between your home LAN (192.168.1.0/24) and a WireGuard VPN. Run it after
connecting to VPN if home devices become unreachable.

## Updating

```bash
cd ~/.dotfiles
git pull
./install.sh # re-runs symlinks, safe to run multiple times
```
99 changes: 57 additions & 42 deletions gitconfig
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# gitconfig — David Stosik's Git config
# Machine-specific settings (name/email/work stuff) go in ~/.gitconfig.local

[include]
# Per-machine overrides: name, email, work remotes, etc.
# Create this file — it won't be committed to dotfiles.
path = ~/.gitconfig.local

[user]
name = David Stosik
email = 816901+davidstosik@users.noreply.github.com
Expand All @@ -13,86 +21,93 @@
[init]
defaultBranch = main

# ── Aliases ───────────────────────────────────────────────────────────────────
[alias]
addp = add --patch
ci = commit --verbose
cia = commit --amend --no-edit
ciam = commit --amend
cim = commit --verbose --message
co = checkout
cob = checkout -b
diffc = diff --cached
addp = add --patch
ci = commit --verbose
cia = commit --amend --no-edit
ciam = commit --amend
cim = commit --verbose --message
co = checkout
cob = checkout -b
diffc = diff --cached
lol = log --decorate --pretty=format:'%C(yellow)%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date=auto:human
pushf = push --force-with-lease
recent = branch --sort=-committerdate --format="%(committerdate:relative)%09%(refname:short)"
st = status
unstage = reset HEAD
find-merge = "!sh -c 'commit=$0 && branch=${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'"
lol = log --decorate --pretty=format:'%C(yellow)%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cd) %C(bold blue)<%an>%Creset' --abbrev-commit --date=auto:human
pushf = push --force-with-lease
recent = branch --sort=-committerdate --format=\"%(committerdate:relative)%09%(refname:short)\"
st = status
unstage = reset HEAD

# ── Colors ────────────────────────────────────────────────────────────────────
[column]
ui = auto

[color "status"]
header = white dim
added = green bold # or updated
changed = yellow bold
untracked = red bold dim
branch = magenta bold
nobranch = red bold
localBranch = magenta bold
remoteBranch = magenta bold
unmerged = red bold ul
header = white dim
added = green bold
changed = yellow bold
untracked = red bold dim
branch = magenta bold
nobranch = red bold
localBranch = magenta bold
remoteBranch = magenta bold
unmerged = red bold ul

[color "diff"]
meta = yellow
context = white dim
whitespace = red reverse
frag = magenta bold
old = red
new = green
meta = yellow
context = white dim
whitespace = red reverse
frag = magenta bold
old = red
new = green

# ── Branch & tag sorting ──────────────────────────────────────────────────────
[tag]
sort = version:refname

[branch]
sort = -committerdate

# ── Rebase ────────────────────────────────────────────────────────────────────
[rebase]
autoSquash = true
autoStash = true
autoStash = true
updateRefs = true

# ── Diff ──────────────────────────────────────────────────────────────────────
[diff]
algorithm = histogram
colorMoved = plain
algorithm = histogram
colorMoved = plain
mnemonicPrefix = true
renames = true
renames = true

# ── Push / Fetch ─────────────────────────────────────────────────────────────
[push]
autoSetupRemote = true
followTags = true
followTags = true

[fetch]
prune = true
prune = true
pruneTags = true
all = true
all = true

# ── Merge ─────────────────────────────────────────────────────────────────────
[merge]
conflictstyle = zdiff3

[pull]
rebase = true

# ── Misc ──────────────────────────────────────────────────────────────────────
[help]
autocorrect = prompt

[commit]
verbose = true

[rerere]
enabled = true
enabled = true
autoupdate = true

[merge]
conflictstyle = zdiff3

[pull]
rebase = true

[feature]
experimental = true
13 changes: 9 additions & 4 deletions gitignore
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
*.DS_Store
# macOS
.DS_Store

# Vim
# Vim swap files
*.swp
*.swo

*~

# Log files
*.log

.claude
# Editor/tool state
.claude

# Machine-local overrides (not committed — put them in ~/.zshrc.local / ~/.gitconfig.local)
*.local
83 changes: 83 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/env bash
# install.sh — set up dotfiles via symlinks
# Safe to run multiple times. Won't overwrite files that aren't symlinks.

set -euo pipefail

DOTFILES="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_DIR="$HOME/.dotfiles-backup/$(date +%Y%m%d-%H%M%S)"

info() { echo " [·] $*"; }
success() { echo " [✓] $*"; }
warn() { echo " [!] $*"; }
error() { echo " [✗] $*" >&2; }

# Symlink $1 (source in dotfiles) to $2 (target in $HOME)
# Backs up existing non-symlink files before replacing.
link_file() {
local src="$1"
local dst="$2"
local dst_dir
dst_dir="$(dirname "$dst")"

mkdir -p "$dst_dir"

if [ -L "$dst" ]; then
# Already a symlink — update it
ln -sf "$src" "$dst"
success "Updated symlink: $dst → $src"
elif [ -e "$dst" ]; then
# Existing file, back it up
mkdir -p "$BACKUP_DIR"
mv "$dst" "$BACKUP_DIR/$(basename "$dst")"
warn "Backed up existing file: $dst → $BACKUP_DIR/"
ln -s "$src" "$dst"
success "Linked: $dst → $src"
else
ln -s "$src" "$dst"
success "Linked: $dst → $src"
fi
}

echo ""
echo "=== Dotfiles install ==="
echo ""

# ── Home directory configs ──────────────────────────────────────────────────
info "Linking home directory configs..."
link_file "$DOTFILES/zshrc" "$HOME/.zshrc"
link_file "$DOTFILES/gitconfig" "$HOME/.gitconfig"
link_file "$DOTFILES/gitignore" "$HOME/.gitignore"
link_file "$DOTFILES/tmux.conf" "$HOME/.tmux.conf"
link_file "$DOTFILES/tmux.mac.conf" "$HOME/.tmux.mac.conf"

# ── Ghostty ─────────────────────────────────────────────────────────────────
info "Linking Ghostty config..."
link_file "$DOTFILES/ghostty.config" "$HOME/.config/ghostty/config"

# ── Neovim ──────────────────────────────────────────────────────────────────
if [ -d "$DOTFILES/nvim" ]; then
info "Linking Neovim config..."
link_file "$DOTFILES/nvim" "$HOME/.config/nvim"
fi

# ── TPM (Tmux Plugin Manager) ────────────────────────────────────────────────
TPM_DIR="$HOME/.tmux/plugins/tpm"
if [ ! -d "$TPM_DIR" ]; then
info "Installing TPM (Tmux Plugin Manager)..."
git clone --depth=1 https://github.com/tmux-plugins/tpm "$TPM_DIR"
success "TPM installed. Start tmux and press prefix + I to install plugins."
else
success "TPM already installed."
fi

echo ""
echo "=== Done! ==="
echo ""
echo "Next steps:"
echo " 1. Restart your shell or run: source ~/.zshrc"
echo " 2. Start tmux, press C-a + I to install tmux plugins"
echo " 3. Run nvim — LazyVim will bootstrap on first launch"
echo " 4. Create ~/.gitconfig.local for machine-specific git settings"
echo " 5. Create ~/.zshrc.local for machine-specific shell settings"
echo ""
5 changes: 5 additions & 0 deletions nvim/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- nvim/init.lua
-- LazyVim bootstrap — plugins and config live in lua/
-- See: https://www.lazyvim.org/

require("config.lazy")
12 changes: 12 additions & 0 deletions nvim/lua/config/autocmds.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-- Autocmds are loaded on the VeryLazy event
-- LazyVim defaults: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/autocmds.lua

-- Add your custom autocmds here
-- Example:
-- vim.api.nvim_create_autocmd("FileType", {
-- pattern = "ruby",
-- callback = function()
-- vim.opt_local.tabstop = 2
-- vim.opt_local.shiftwidth = 2
-- end,
-- })
5 changes: 5 additions & 0 deletions nvim/lua/config/keymaps.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Keymaps are loaded on the VeryLazy event
-- LazyVim defaults: https://github.com/LazyVim/LazyVim/blob/main/lua/lazyvim/config/keymaps.lua

-- Add your custom keymaps here
-- Example: vim.keymap.set("n", "<leader>X", ":SomeCommand<CR>", { desc = "Do something" })
Loading