Skip to content

Latest commit

 

History

History
269 lines (198 loc) · 8.08 KB

File metadata and controls

269 lines (198 loc) · 8.08 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Repository Overview

This is a dotfiles repository managed by Chezmoi. It contains personal configuration files for a cross-platform development environment (macOS, Linux/WSL) with automated setup via Ansible.

Key Technologies

  • Chezmoi: Dotfile manager with templating support (.tmpl files)
  • Ansible: Automated system setup and package installation
  • ZSH: Shell with Zplug for plugin management
  • Neovim: Terminal editor using kickstart.nvim (nvim-custom) and LazyVim (nvim-lazyvim)
  • Tmux: Terminal multiplexer with TPM for plugins
  • Hammerspoon: macOS desktop automation (Lua-based)

Ansible Design Decisions

@./ansible/README.md

Common Commands

Chezmoi Operations

# Apply changes and reload shell
ma

# Edit dotfiles (opens chezmoi source dir in editor)
edit

# Navigate to chezmoi source directory
moicd
# or
cd ~/.local/share/chezmoi

# Run git commands on dotfiles repo from anywhere
gmoi <git-command>

# Add nvim config to chezmoi (removes lazy-lock.json)
moi_add_nvim

Ansible Playbook

# Run full ansible playbook to configure system
dotansible

# Interactive tag selection with fzf
dotansible -i

# Run specific ansible tasks by tag
dotansible brew      # Install/update Homebrew packages only
dotansible packages  # Install all packages (brew or apt)
dotansible zsh       # Configure ZSH only
dotansible tmux      # Configure tmux only

# List available tags
dotansible tags

# For WSL (prompts for sudo password)
dotansible --ask-become

# First-time setup scripts
./ansible/mac-setup.sh      # macOS
./ansible/fedora-setup.sh   # Fedora Linux

The dotansible function automatically uses hostname-specific inventory files when available (e.g., ansible/inventory/GVXPDWWKWG.yml), falling back to main.yml.

Shell Management

# Reload zsh configuration
sz

# View zsh configuration
catrc

Neovim Configurations

# Switch between neovim configs interactively
vv

# Current default config (set via NVIM_APPNAME)
nvim-custom  # kickstart.nvim based
nvim-lazyvim # LazyVim distribution

Tmux

# Session manager (uses sesh + fzf)
# Bound to Alt+s in tmux

Architecture

Chezmoi Template System

Files with .tmpl extension are processed as Go templates. Key variables:

  • {{ .chezmoi.os }} - OS detection ("darwin" or "linux")
  • {{ .chezmoi.hostname }} - Machine hostname for machine-specific configuration
  • Conditional blocks enable OS-specific and hostname-specific configuration

Example from dot_zshrc.tmpl:

{{ if eq .chezmoi.os "darwin" -}}
# macOS specific configuration
{{ end -}}

{{ if eq .chezmoi.hostname "GVXPDWWKWG" -}}
# Zendesk work machine configuration
{{ end -}}

Ansible Structure

Main playbook: ansible/main.yml

  • Targets: localhost (127.0.0.1)
  • Roles: zsh, hammerspoon (macOS only)
  • Tasks: apt/homebrew package management, nodenv, tmux, vundle

Inventory files: ansible/inventory/

  • Machine-specific configs named by hostname
  • main.yml is the default inventory

Tasks: ansible/tasks/

  • apt.yml - Debian/Ubuntu packages
  • homebrew.yml - macOS packages
  • nodenv.yml - Node.js version management
  • tmux.yml - Tmux plugin manager setup
  • vundle.yml - Vim plugin setup

Roles: ansible/roles/

  • zsh/ - ZSH installation and configuration
  • hammerspoon/ - macOS window management (macOS only)
  • Additional roles: desktop-background, emacs, lastpass, lock-screen, music, pacman

ZSH Configuration

Structure:

  • .zshenv - Environment variables, sourced first
  • .zprofile - Login shell configuration
  • .zshrc - Interactive shell setup, sources aliases.zsh
  • aliases.zsh - All shell aliases and functions

Plugin management: Zplug

  • Plugins: vi-mode, agnoster theme, zsh-autosuggestions, zsh-syntax-highlighting
  • Custom keybinds: fd for vi command mode, lk to accept suggestions

Key integrations:

  • fzf - fuzzy finder
  • zoxide - smart directory jumping
  • sesh - tmux session manager (Alt+s keybind)

Neovim Configurations

nvim-custom: Kickstart.nvim fork

  • Single-file init.lua with extensive documentation
  • Uses lazy.nvim for plugin management
  • Located: dot_config/nvim-custom/

nvim-lazyvim: LazyVim distribution

  • More opinionated, feature-complete setup
  • Located: dot_config/nvim-lazyvim/

Switch between configs using the vv function or by setting NVIM_APPNAME.

Development Workflow

Making Changes to Dotfiles

  1. Navigate to chezmoi source: moicd or edit
  2. Edit files in the source directory
  3. For templated files, edit the .tmpl version
  4. Apply changes: ma (applies and reloads shell)
  5. Commit changes: gmoi add . and gmoi commit

Adding New Configuration Files

# Add a file to chezmoi management
chezmoi add ~/.config/newapp/config.yml

# Add with auto-template generation
chezmoi add --autotemplate ~/.gitconfig

Ansible Customization

Create machine-specific inventory:

cp ansible/inventory/main.yml ansible/inventory/$(hostname).yml

Edit the new inventory file, then run:

ansible-playbook ansible/main.yml -i ansible/inventory/$(hostname).yml

Machine-Specific Configuration

Machine-specific configurations are determined by hostname using chezmoi's built-in {{ .chezmoi.hostname }} variable in templates. No additional configuration files are needed.

Using hostname in templates:

{{ if eq .chezmoi.hostname "GVXPDWWKWG" -}}
# Zendesk work machine configuration (zetup, zendesk tooling, SSH keys, etc.)
{{ end -}}

To add configuration for a new machine:

  1. Get the hostname: hostname
  2. Add conditionals to templates based on the hostname
  3. Use {{ .chezmoi.os }} for OS-specific configuration (darwin/linux)
  4. Combine conditions as needed for specific machine + OS combinations

This hostname-based approach:

  • Requires no manual configuration files
  • Makes machine identity explicit in templates
  • Works automatically when dotfiles are applied to any machine
  • Easy to add new machines by adding hostname checks to templates

Platform-Specific Notes

macOS:

  • Homebrew packages managed via ansible/tasks/homebrew.yml
  • Hammerspoon requires manual first-time setup
  • rbenv path: ~/.rbenv/versions/3.3.3/bin

Linux/WSL:

  • APT packages managed via ansible/tasks/apt.yml
  • Alacritty settings in Windows: C:\Users\Patrick\AppData\Roaming\Alacritty\
  • Use alacritty_settings_update to sync config to Windows (WSL only)
  • rbenv path: ~/.rbenv/versions/3.3.4/bin

File Naming Conventions

Chezmoi uses special prefixes in the source directory:

  • dot_. at any level (e.g., dot_zshrc.zshrc, dot_config/.config/)
  • .tmpl suffix → Go template processing
  • executable_ → Make file executable
  • private_ → Set file permissions to 0600

Examples of the directory structure mapping:

  • dot_config/nvim/init.lua~/.config/nvim/init.lua
  • dot_zsh/dot_zprofile.tmpl~/.zsh/.zprofile (templated)
  • dot_tmux.conf~/.tmux.conf

The dot_ prefix is used every time a dot is needed in the path, whether for directories or files.

Important Paths

  • Chezmoi source: $HOME/.local/share/chezmoi
  • Global Claude instructions (tracked in private dotfiles): ~/code/dotfiles-private/dot_claude/CLAUDE.md - this is the primary place for user preferences that apply across all projects
  • Config files: ~/.config/
  • Local binaries: ~/.local/bin
  • ZSH configs: $ZDOTDIR (usually ~/.zsh/)
  • Tmux plugins: ~/.tmux/plugins/
  • Node versions: ~/.nodenv/versions/
  • never use emojis in commit messages, nor co-authoring from claude, nor mentions of it being generated by claude
  • always update the links in the readme toc when adding/removing files in docs/
  • Ansible should not report tasks as "changed" when they haven't changed the state of the machine.
  • NEVER create dotfiles directly on the system (e.g. in ~/.emacs.d.han/, ~/.config/, etc.). Always create them in the chezmoi source directory (~/.local/share/chezmoi/) so they are tracked and deployed properly via chezmoi apply.