Skip to content

Latest commit

Β 

History

History
314 lines (218 loc) Β· 13 KB

File metadata and controls

314 lines (218 loc) Β· 13 KB

🏠 Dotfiles

Personal development environment configuration files managed with GNU Stow.

Terminal Setup

Read the blog post: The Tools That Make My Terminal Work β€” A deep dive into how these configurations come together into a cohesive workflow.

πŸ“‹ Overview

This repository contains my complete development environment setup, organized for easy deployment across personal and work machines while keeping sensitive work configurations private.

Features

  • πŸ”§ GNU Stow-based - Simple symlink management, no complex templating
  • ❄️ Nix-darwin managed - Declarative macOS system configuration with reproducible environments
  • 🏠 Work/Personal separation - Different configs for different contexts
  • πŸ”’ Private work configs - Sensitive company data kept in private submodule
  • 🎨 Consistent theming - Tokyo Night and Catppuccin themes across tools
  • ⌨️ Vi-mode everywhere - Consistent navigation patterns
  • πŸ” Fuzzy finding - FZF integration throughout the workflow

πŸš€ Quick Start

πŸ†• Fresh Machine (one command)

On a brand-new Mac with nothing but a shell, clone the repo and run the interactive bootstrap:

git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
./install.sh --bootstrap

--bootstrap is idempotent and handles each step only if needed:

  • Generates an SSH key (and pauses for you to add it to GitHub)
  • Offers to rename the host via scutil
  • Installs Nix if it's missing
  • Creates an empty shared/.config/nix-darwin/machines/<hostname>.nix for new hosts (auto-discovered by the flake β€” no manual edits)
  • Bootstraps nix-darwin on first run, or calls nix_rebuild thereafter
  • Prompts to initialize private submodules
  • Runs profile .hooks/pre-stow.sh scripts (install deps, remove conflicting files)
  • Runs stow with profiles you pick (defaults to shared personal on macOS)
  • Runs profile .hooks/post-stow.sh scripts (TPM install, bat cache rebuild)

🏠 Personal Machine (existing setup)

cd ~/.dotfiles
nix_rebuild                    # Apply nix-darwin config
./install.sh shared personal   # Symlink user-level configs

πŸ’Ό Work Machine (existing setup)

cd ~/.dotfiles
git submodule update --init --recursive
nix_rebuild                    # Auto-detects work machines via hostname
./install.sh shared work

Removing Work Submodule

When you're done working with the work submodule and want to remove it from your machine:

git submodule deinit -f work

This clears the work/ directory and unregisters the submodule without affecting the main repository.

🐧 Ubuntu Server

git clone git@github.com:josephschmitt/dotfiles.git ~/.dotfiles
cd ~/.dotfiles

# Install user-level configuration files
./install.sh shared ubuntu-server

See the ubuntu-server README for details on the Nix configuration and system services included.

πŸ“¦ What's Included

πŸ› οΈ Core Tools

  • 🐚 Multi-Shell Setup: Fish (primary), Zsh (secondary), Bash (fallback)
    • Shared configuration modules to eliminate duplication
    • POSIX-compliant environment setup across all shells
    • macOS login shell compatibility
  • ✏️ Editors:
    • Neovim (Kickstart) - Default, mapped to nvim/vim commands
    • Neovim (AstroVim) - Available via astrovim alias
    • Neovim (LazyVim) - Available via lazyvim alias
    • Helix - Secondary modal editor for quick edits
  • πŸ’» Terminal: Ghostty with optimized configuration
  • πŸ”€ Multiplexer: tmux with plugin ecosystem, Zellij as alternative
  • 🌳 Version Control: Git with comprehensive aliases

πŸ”§ Development Environment

  • ❄️ System Management: nix-darwin for declarative macOS configuration
  • πŸ“¦ Package Management: Nix packages + Homebrew integration
  • 🌐 Languages: Node.js, Rust, Python, Go configurations
  • πŸ”¨ Package Managers: pnpm, bun, cargo, asdf, volta
  • ⚑ CLI Tools: FZF, EZA, Yazi, sesh, leader-key, ripgrep, fd, and more

⚑ Productivity Features

  • 🌢️ Git workflow optimization with git-spice and lazygit
  • πŸ” Fuzzy finding for files, history, and processes
  • πŸ’Ύ Session management with sesh and tmux persistence
  • ⌨️ Custom keybindings for efficient navigation
  • πŸ€– AI assistance with OpenCode integration

✏️ Neovim Setup

This configuration includes three complete Neovim setups that coexist independently via Neovim's NVIM_APPNAME feature:

Kickstart (Default)

Location: shared/.config/nvim/ Aliases: nvim, vim (bare command, no NVIM_APPNAME)

A bespoke, from-scratch configuration built on kickstart.nvim. Every plugin is intentionally chosen and understood.

Features:

  • Snacks dashboard with custom JoeVim ASCII art
  • Neo-tree file explorer with tmux-style navigation
  • Snacks picker (fuzzy finder for files, grep, LSP symbols)
  • Bufferline tab bar with ordinal numbering
  • Tokyonight Moon theme with custom highlights
  • Fast startup (~50ms) via aggressive lazy-loading

Documentation: See shared/.config/nvim/README.md

AstroVim

Location: shared/.config/astronvim/ Aliases: astrovim

Built on AstroVim, a community-driven Neovim distribution.

Features:

  • Community-driven plugin ecosystem (AstroCommunity)
  • Catppuccin Mocha theme with custom dashboard
  • Multi-cursor editing, Yazi file manager integration
  • Comprehensive window/tab management keybindings

Documentation: See shared/.config/astronvim/README.md

LazyVim

Location: shared/.config/lazyvim/ Aliases: lazyvim

Built on LazyVim, a feature-rich Neovim starter configuration.

Features:

  • Full IDE experience with LSP, completion, debugging
  • Extensive plugin ecosystem via lazy.nvim
  • AI-powered coding (Avante, CodeCompanion, Copilot)

Documentation: See shared/.config/lazyvim/README.md

Switching Between Configs

All three configurations are completely independent (separate plugins, data, state, cache) and coexist without conflicts.

Currently: The nvim and vim commands launch the Kickstart config. AstroVim and LazyVim are accessed via their respective aliases (which set NVIM_APPNAME).

Why three configs? The Kickstart config is the daily driver β€” built from scratch for full understanding. AstroVim and LazyVim serve as references and fallbacks.

πŸ“ Repository Structure

dotfiles/
β”œβ”€β”€ shared/          # Common configurations for all machines
β”‚   β”œβ”€β”€ .config/     # Application configurations
β”‚   β”‚   β”œβ”€β”€ nix-darwin/    # Declarative macOS system configuration
β”‚   β”‚   β”œβ”€β”€ fish/          # Fish shell configuration
β”‚   β”‚   β”œβ”€β”€ nvim/          # Neovim configuration (Kickstart β€” default)
β”‚   β”‚   β”œβ”€β”€ lazyvim/       # Neovim configuration (LazyVim)
β”‚   β”‚   β”œβ”€β”€ astronvim/     # Neovim configuration (AstroVim)
β”‚   β”‚   β”œβ”€β”€ tmux/          # Tmux multiplexer
β”‚   β”‚   β”œβ”€β”€ ghostty/       # Ghostty terminal emulator
β”‚   β”‚   └── ...            # Other tool configurations
β”‚   β”œβ”€β”€ bin/         # Utility scripts (nix_rebuild wrapper, etc.)
β”‚   β”œβ”€β”€ .zshrc       # Shell configurations
β”‚   └── README.md    # Detailed setup instructions
β”œβ”€β”€ personal/        # Personal-specific configurations
β”‚   β”œβ”€β”€ .config/nix-darwin/machines/mac-mini.nix  # Personal machine
β”‚   └── .gitconfig   # Personal git settings
β”œβ”€β”€ ubuntu-server/   # Ubuntu server-specific configurations
β”‚   └── .config/nix/ # Nix configuration for Ubuntu servers
└── work/            # Work-specific configurations (private submodule)

πŸ“š Documentation

For complete setup instructions, troubleshooting, and maintenance information, see:

❄️ Nix-darwin: System-Level Configuration Management

A major component of this setup is nix-darwin, which provides declarative macOS system configuration. This means your entire system setupβ€”packages, applications, system preferences, and moreβ€”is defined as code.

Why nix-darwin?

Reproducibility: Define your entire system configuration once, apply it consistently across multiple machines. No more manually clicking through System Preferences or running installation scripts.

Rollbacks: Every system change creates a new "generation." If something breaks, roll back to a previous working state instantly.

Machine-specific configurations: Share common settings across all machines while maintaining machine-specific customizations (home server vs. work laptop).

What It Manages

  • System packages: CLI tools, development utilities (installed via Nix)
  • GUI applications: Apps like Ghostty, VS Code, Arc browser (via Homebrew integration)
  • System preferences: Dock position, Finder settings, keyboard behavior, etc.
  • Services: Background daemons (e.g., Docker Compose on home server)
  • Fonts: Nerd Fonts for terminal compatibility

Quick Usage

# Apply system configuration changes
nix_rebuild

# Update package versions
nix_update

# Both: update packages then rebuild
nix_update && nix_rebuild

The nix_rebuild alias intelligently detects whether you're on a personal or work machine and applies the appropriate configuration automatically.

Integration with Dotfiles

  • Nix-darwin handles: System-wide packages, GUI apps, macOS preferences
  • Stow handles: User-level configuration files (shell configs, editor settings, etc.)

This separation means nix-darwin manages what's installed and how the system behaves, while your dotfiles manage how those tools are configured.

For detailed nix-darwin setup, machine configurations, and troubleshooting, see the Nix-darwin README.

🎯 Core Philosophy

This dotfiles repository is built around several key principles that prioritize maintainability, Unix best practices, and real-world usability.

1. 🎯 Simplicity Over Complexity

"Files are files" - No complex templating, generation, or build systems. What you see in the repository is exactly what gets deployed. This makes the configuration:

  • Debuggable: Easy to trace issues to specific files
  • Portable: Works anywhere without special tooling
  • Understandable: New contributors can immediately see what's happening
  • Reliable: No hidden dependencies or generation failures

2. 🐧 Unix Best Practices with Modern Realities

The shell configuration follows traditional Unix conventions while acknowledging modern multi-shell workflows:

Traditional Unix Approach:

  • .profile - POSIX-compliant environment setup (PATH, exports)
  • Shell-specific rc files - Interactive configuration only
  • Proper sourcing hierarchy - Login vs non-login shell handling

Modern Adaptations:

  • Shared modules (.config/shell/) - Eliminate duplication across shells
  • macOS compatibility - Proper login shell handling
  • Multi-shell support - Fish, Zsh, and Bash coexist harmoniously

Why This Matters:

  • No duplication: Environment variables and aliases defined once
  • Consistency: Same behavior across all shells
  • Flexibility: Each shell can leverage its unique features
  • Maintainability: Changes propagate automatically

3. πŸ”’ Security Through Separation

Work/Personal Isolation:

  • Public sharing safe - Personal configs can be shared openly
  • Private submodule - Work-specific configs stay in company-controlled repository
  • Context switching - Different git identities and tool configurations per environment
  • Compliance friendly - Meets corporate security requirements

4. πŸ› οΈ Practical Over Perfect

Real-world considerations:

  • macOS compatibility - Handle platform-specific shell behavior
  • Multiple package managers - Support for the tools actually used (npm, pnpm, bun, cargo, etc.)
  • Fallback compatibility - Bash support for systems where Fish/Zsh aren't available
  • Tool integration - Configurations work together (tmux + vim navigation, fzf everywhere)

5. πŸ“– Documentation as Code

Self-documenting approach:

  • Clear file organization - Purpose obvious from structure
  • Comprehensive READMEs - Both for humans and AI assistants
  • Inline comments - Explain non-obvious decisions
  • Philosophy preservation - Guidelines prevent architectural drift

This philosophy ensures the dotfiles remain maintainable and useful as tools, workflows, and requirements evolve over time.