No description
  • Shell 73.2%
  • Go Template 26.3%
  • Dockerfile 0.5%
Find a file
Ryan Lewis e5913b275c
docs: fix stale claims in README and SCRIPTS
- README: zsh is the default shell with fish as the mirrored
  alternative (was the reverse); Ghostty not iTerm2; add Java to the
  runtime list; strip hardcoded runtime versions (already drifted -
  Go said 1.26.1 vs 1.26.4 pinned) in favour of pointing at the mise
  config as source of truth
- SCRIPTS: install.sh takes no CLI options (it is a minimal chezmoi
  bootstrap; behaviour is driven by CI/QUICK_INSTALL env vars), and
  setup-aliases.sh is called by docker-test.sh, not install.sh
2026-06-05 15:22:28 +01:00
.chezmoiscripts feat(shell): recommend zsh, not fish, as login shell on fresh machines 2026-06-05 15:22:28 +01:00
.claude docs: make extend-dotfiles skill + CLAUDE.md dual-shell (zsh default) 2026-06-04 20:49:51 +01:00
.github/workflows chore(deps): update macos to 26 (#55) 2026-05-27 07:02:05 +01:00
dot_claude Revert "fix(claude): mark settings.json executable to stop apply chmod churn" 2026-06-05 15:06:42 +01:00
private_dot_config refactor: drop all asdf remnants, java env comes from mise 2026-06-05 15:11:54 +01:00
private_dot_gnupg Manage gpg-agent.conf so fresh machines wire up pinentry 2026-05-08 13:00:45 +01:00
.chezmoi.toml.tmpl Replace hardcoded work hostname with isWork prompt 2026-04-23 01:12:12 +01:00
.chezmoiexternal.toml.tmpl feat(zsh): add zsh config mirroring the fish setup 2026-06-04 20:36:16 +01:00
.chezmoiignore Replace hardcoded work hostname with isWork prompt 2026-04-23 01:12:12 +01:00
.chezmoiremove Remove cursor-code-orchestrator agent 2026-04-21 11:29:13 +01:00
.dockerignore fix: convert remaining CRLF files to LF and enforce repo-wide 2026-02-12 13:32:57 +00:00
.editorconfig feat: add .editorconfig for consistent code formatting 2025-08-14 19:59:47 +01:00
.gitattributes fix: convert remaining CRLF files to LF and enforce repo-wide 2026-02-12 13:32:57 +00:00
.gitignore chore(claude): add PostToolUse hook nudging README refresh 2026-06-03 02:16:39 +01:00
.tool-versions chore(deps): update golang to 1.26.4 (#57) 2026-06-03 03:48:13 +01:00
CLAUDE.md feat(shell): recommend zsh, not fish, as login shell on fresh machines 2026-06-05 15:22:28 +01:00
docker-test.sh refactor: drop all asdf remnants, java env comes from mise 2026-06-05 15:11:54 +01:00
Dockerfile chore(deps): update ubuntu Docker tag to v26 (#51) 2026-05-27 07:02:08 +01:00
dot_gitconfig.tmpl Enable SSH commit signing and prefer helix editor 2026-04-21 11:34:24 +01:00
dot_inputrc fix: convert dot_inputrc from CRLF to LF line endings 2026-02-12 13:29:07 +00:00
dot_lesskey fix: convert remaining CRLF files to LF and enforce repo-wide 2026-02-12 13:32:57 +00:00
dot_tmux.conf added battery to tmux 2026-03-24 12:38:23 +00:00
dot_zshenv.tmpl feat(zsh): add zsh config mirroring the fish setup 2026-06-04 20:36:16 +01:00
dot_zshrc.tmpl refactor: drop all asdf remnants, java env comes from mise 2026-06-05 15:11:54 +01:00
install.sh fix: set TMPDIR for WSL/Linux compatibility 2025-08-14 19:44:29 +01:00
README.md docs: fix stale claims in README and SCRIPTS 2026-06-05 15:22:28 +01:00
renovate.json refactor: drop all asdf remnants, java env comes from mise 2026-06-05 15:11:54 +01:00
SCRIPTS.md docs: fix stale claims in README and SCRIPTS 2026-06-05 15:22:28 +01:00
setup-aliases.sh feat: initial commit 2025-08-08 02:43:50 +01:00
test-chezmoi-data.yaml feat: initial commit 2025-08-08 02:43:50 +01:00
test.sh feat(zsh): add zsh config mirroring the fish setup 2026-06-04 20:36:16 +01:00

Cross-Platform Dotfiles with Chezmoi

This repository contains my personal dotfiles managed by chezmoi, supporting both Linux and macOS. Zsh is the default shell, with a parallel Fish configuration kept feature-for-feature in sync.

Features

  • 🦓 Zsh configuration (the default shell) with cross-platform support
  • 🐟 Fish configuration that mirrors the Zsh setup feature-for-feature
  • 🍎 macOS-specific optimizations (Homebrew, Ghostty, etc.)
  • 🐧 Linux compatibility
  • 🛠️ Useful shell functions and utilities (ported 1:1 across both shells)
  • 📦 Template-based configuration for different environments
  • 🔧 mise for language runtimes (Node.js, Python, Go, Bun, Java)
  • 🌊 mise aqua backend for 22 modern CLI tools (bat, fd, eza, kubectl, gh, etc.)
  • 🔍 Modern CLI tools: Complete suite of replacements for traditional Unix tools
  • Starship cross-shell prompt with git integration
  • 📜 Atuin for enhanced shell history (better search, statistics, deduplication)
  • 🧹 Automatic cleanup of old tool installations

Prerequisites

  • Git
  • curl or wget
  • sudo access (for package installation)

Installation

# One-liner installation
curl -fsLS https://raw.githubusercontent.com/ryanlewis/dotfiles/main/install.sh | bash

Or if you prefer using wget:

wget -qO- https://raw.githubusercontent.com/ryanlewis/dotfiles/main/install.sh | bash

Alternative: Using Chezmoi Directly

If you already have chezmoi installed:

chezmoi init --apply ryanlewis/dotfiles

Environment Variables

Control installation behavior with these environment variables:

# Skip language runtimes (Node.js, Python, Go)
QUICK_INSTALL=true curl -fsLS https://raw.githubusercontent.com/ryanlewis/dotfiles/main/install.sh | bash

# Provide git config to avoid prompts
CHEZMOI_USER_NAME="Your Name" CHEZMOI_USER_EMAIL="you@example.com" \
  curl -fsLS https://raw.githubusercontent.com/ryanlewis/dotfiles/main/install.sh | bash

What Gets Installed

The installation process automatically sets up:

  1. Fish shell - Modern, user-friendly shell
  2. chezmoi - Dotfiles manager
  3. mise - Universal version manager
  4. Modern CLI tools:
    • eza - Better ls
    • bat - Better cat with syntax highlighting
    • ripgrep - Better grep
    • fd - Better find
    • fzf - Fuzzy finder
    • zoxide - Smarter cd
    • starship - Cross-shell prompt
    • btop - Better top
    • duf - Better df
    • dust - Better du
    • gum - Pretty shell scripts
    • kubectl - Kubernetes CLI
    • kubectx - K8s context switcher
    • kubens - K8s namespace switcher
    • And more...
  5. Language runtimes (optional):
    • Node.js (via mise)
    • Python/Miniconda (via mise)
    • Go (via mise)
    • Bun (via mise)

Usage

Common Commands

  • chezmoi diff - See what changes would be made
  • chezmoi apply - Apply the configuration
  • chezmoi add ~/.config/fish/newfile.fish - Add a new file
  • chezmoi edit ~/.config/fish/config.fish - Edit a managed file
  • chezmoi update - Pull latest changes and apply

Fish Functions

This configuration includes several useful Fish functions:

  • mkcd <dir> - Create a directory and cd into it
  • backup <file> - Create a timestamped backup of a file
  • extract <archive> - Extract various archive formats
  • update - Update system packages (brew/apt/dnf/pacman)
  • ports - Show listening ports
  • myip - Display local and public IP addresses
  • yank - Copy text to clipboard via OSC 52 (works over SSH)
  • mise-setup - Show configured mise tools and install hints
  • mise-install-latest - Install latest stable versions of all tools
  • mise-update - Update mise and all plugins

Clipboard Function: yank

The yank function enables clipboard access from anywhere, even over SSH:

# Copy command output
git diff | yank
cat ~/.ssh/id_rsa.pub | yank
echo "some text" | yank

# Works over SSH - copies to your local clipboard!
ssh server "cat /var/log/nginx/error.log | yank"

Why use yank?

  • Works over SSH without X11 forwarding
  • Works in tmux/screen sessions
  • Universal solution across different terminals (iTerm2, Terminal.app, Alacritty, Windows Terminal, etc.)
  • No need for platform-specific tools (pbcopy/xclip)

FZF-Powered Functions

  • fcd - Fuzzy change directory with preview
  • fopen - Fuzzy find and open file in editor
  • fkill - Fuzzy find and kill processes
  • fgrep <term> - Fuzzy grep with file preview
  • fgit <cmd> - Interactive git operations:
    • fgit add - Stage files interactively
    • fgit checkout - Checkout branches with preview
    • fgit log - Browse git log with commit preview
    • fgit diff - View file diffs interactively

macOS-Specific Features

When running on macOS, additional features are enabled:

  • Homebrew integration
  • GNU coreutils in PATH (if installed)
  • macOS-specific aliases:
    • flushdns - Flush DNS cache
    • ql <file> - Quick Look preview
    • showfiles/hidefiles - Toggle hidden files in Finder
    • cleanup - Remove .DS_Store files

Modern CLI Tools

This configuration includes a comprehensive suite of modern CLI tools:

File & Directory Tools

  • eza - Modern ls replacement
    • Icons, colors, git integration, tree view
    • Aliased to replace all ls variants
  • fd - Better find
    • Simple syntax, respects .gitignore
    • Default file finder for fzf
  • ripgrep - Better grep
    • Extremely fast, respects .gitignore
    • Powers the fgrep function
  • bat - Better cat
    • Syntax highlighting, line numbers
    • File previews in fzf
  • zoxide - Smarter cd
    • Learns your most used directories
    • Jump with partial names

System Monitoring

  • btop - Better top/htop
    • Beautiful terminal UI
    • Aliased to replace top and htop
  • duf - Better df
    • User-friendly disk usage display
  • dust - Better du
    • Intuitive disk usage analyzer

Development Tools

  • lazygit - Terminal UI for git
    • Interactive staging, branching, merging
    • Launch with lg
  • delta - Better git diffs
    • Syntax highlighting, side-by-side view
    • Auto-configured in gitconfig
  • gh - GitHub CLI
    • Manage PRs, issues from terminal
  • httpie - Better curl
    • Human-friendly HTTP client
    • https alias for HTTPS requests
  • jq - JSON processor
    • Query and manipulate JSON data
  • just - Modern make
    • Simpler command runner

Shell Enhancements

  • fzf - Fuzzy finder
    • Ctrl+R (history), Ctrl+T (files), Alt+C (directories)
    • Powers many custom functions
  • starship - Cross-shell prompt
    • Fast, customizable, git-aware
    • Pre-configured with icons
  • atuin - Better shell history
    • Advanced fuzzy search, statistics, intelligent deduplication
  • direnv - Directory environments
    • Auto-load .envrc files
  • broot - Better tree
    • Navigate directories efficiently
  • tldr - Simplified man pages
    • Quick command examples

Container & Kubernetes Tools

  • kubectl - Kubernetes CLI
    • Manage Kubernetes clusters
  • kubectx - Context switcher
    • Quickly switch between Kubernetes contexts
  • kubens - Namespace switcher
    • Quickly switch between Kubernetes namespaces

Version Management with mise

This configuration includes mise for managing:

Language Runtimes (5 tools):

  • Node.js (LTS)
  • Python (via Miniconda)
  • Go
  • Bun
  • Java (Eclipse Temurin LTS)

CLI Tools via aqua backend (22 tools):

  • Modern CLI replacements: bat, fd, eza, ripgrep, zoxide, duf, dust
  • Development tools: fzf, starship, atuin, delta, lazygit, gh, jq, just, gum, direnv, uv
  • Kubernetes tools: kubectl, kubectx, kubens
  • AWS tools: granted

Versions above track private_dot_config/mise/config.toml.tmpl, which is the source of truth.

All tools are automatically installed via ~/.config/mise/config.toml when you run:

# Install all configured tools (languages + CLI tools)
mise install

# Or install latest stable versions
mise-install-latest

Note: Old installations (Homebrew, apt packages, binaries) are automatically cleaned up after mise aqua setup.

Development

Making Changes to Dotfiles

After installation, your dotfiles are managed by chezmoi. To make changes:

# Go to chezmoi's source directory
chezmoi cd

# Edit files directly
vim .config/fish/config.fish.tmpl

# Preview changes
chezmoi diff

# Apply changes locally
chezmoi apply

# Commit and push
git add -A
git commit -m "Update fish config"
git push

Or use the included dotfiles Fish function:

dotfiles edit     # Go to source directory
dotfiles diff     # Preview changes
dotfiles apply    # Apply locally
dotfiles push     # Commit and push all changes
dotfiles pull     # Pull latest from GitHub

Updating from GitHub

On any machine with your dotfiles installed:

chezmoi update    # Pull latest changes and apply them

Customization

Local Configuration

Create ~/.config/fish/config.local.fish (Fish) or ~/.config/zsh/config.local.zsh (Zsh) for machine-specific configuration that won't be managed by chezmoi.

Zsh (the default shell)

Zsh is the default login shell (the provisioning script recommends it on fresh machines; chsh -s $(which zsh) to switch an existing one). A parallel Fish configuration is kept feature-for-feature in sync for when an interactive-first shell is preferred. The Zsh side comprises:

  • ~/.zshenv — PATH/environment for all shells (the non-interactive half of config.fish).
  • ~/.zshrc — interactive config: vi mode, completions, abbreviations, tool inits (mise, zoxide, fzf, atuin, starship, direnv, broot), aliases, and the same MOTD/greeting.
  • ~/.config/zsh/functions/*.zsh — a 1:1 port of every Fish function (mkcd, extract, fcd, fgit, ca, crpr, tools, …).
  • ~/.config/zsh/conf.d/*.zsh — fzf options, macOS extras, greeting, and MOTD.

The prompt (starship), history (atuin), and the modern-CLI aliases are shared, so both shells behave identically.

Plugins that Fish ships built-in (autosuggestions, syntax highlighting) plus zsh-abbr are fetched by chezmoi into ~/.config/zsh/plugins (see .chezmoiexternal.toml) — there is no separate plugin manager.

Try it without switching: just run zsh. To make it your login shell when ready: chsh -s "$(command -v zsh)".

Templates

This repository uses chezmoi templates to handle OS-specific differences. Key template variables:

  • {{ .chezmoi.os }} - "darwin" or "linux"
  • {{ .chezmoi.arch }} - System architecture
  • {{ .brewPrefix }} - Homebrew prefix path
  • {{ .packageManager }} - System package manager

Directory Structure

~/dev/dotfiles/
├── .chezmoi.toml.tmpl          # Chezmoi configuration template
├── .chezmoiignore              # Files to ignore by OS
├── .chezmoiexternal.toml.tmpl  # Externally-fetched files (zsh plugins)
├── dot_zshenv.tmpl             # Zsh env for all shells (PATH, etc.)
├── dot_zshrc.tmpl              # Main Zsh interactive config
├── private_dot_config/
│   ├── private_fish/
│   │   ├── config.fish.tmpl    # Main Fish config
│   │   ├── functions/          # Fish functions
│   │   └── conf.d/             # Fish conf.d files
│   └── zsh/
│       ├── functions/          # Zsh functions (1:1 port of Fish)
│       └── conf.d/             # Zsh conf.d files (fzf, macos, greeting, motd)
└── README.md                   # This file

Testing with Docker

You can test the dotfiles installation in a clean Docker environment:

Quick Test

# Run the interactive test script
./docker-test.sh

# Inside the container:
cd /home/testuser/dev/dotfiles
./install.sh
fish
./test.sh  # Run the test suite

Manual Docker Commands

# Build the test image
docker build -f Dockerfile.test -t dotfiles-test .

# Run container with mounted dotfiles
docker run -it --rm -v "$(pwd):/home/testuser/dev/dotfiles:ro" dotfiles-test

# Or use docker-compose
docker-compose up -d dotfiles-test
docker exec -it dotfiles-test fish

Test Script

The test.sh script verifies all tools are installed correctly:

  • Checks all CLI tools are available
  • Verifies Fish functions exist
  • Confirms configurations are in place
  • Tests mise tools

CI/CD

This repository includes automated testing via GitHub Actions:

Continuous Integration

  • Tests on Ubuntu 22.04 and 24.04
  • Tests on macOS 13 and 14
  • Docker-based testing
  • Full tool installation verification

Running in CI Mode

# Install with CI mode (non-interactive)
./install.sh --ci

# Or just skip confirmations
./install.sh --no-confirm

Environment variables for CI:

  • CI=true - Automatically detected by GitHub Actions
  • CHEZMOI_USER_NAME - Name for git config
  • CHEZMOI_USER_EMAIL - Email for git config

Troubleshooting

Installation Issues

Python/Miniconda fails with "Terms of Service" error

This is a known issue with Miniconda requiring ToS acceptance. The script will continue without Python. To fix:

# Accept Conda ToS manually
~/.local/share/mise/installs/python/miniconda3-latest/bin/conda init
~/.local/share/mise/installs/python/miniconda3-latest/bin/conda config --set auto_activate_base false

Script fails with "command not found"

Ensure ~/.local/bin is in your PATH:

export PATH="$HOME/.local/bin:$PATH"

Fish doesn't start with correct configuration

# Re-apply dotfiles
chezmoi apply -v

# Install Fisher plugins manually
fish -c "curl -sL https://raw.githubusercontent.com/jorgebucaran/fisher/main/functions/fisher.fish | source && fisher install jorgebucaran/fisher"
fish -c "fisher install PatrickF1/fzf.fish"

Tools not found after installation

# Activate mise in current shell
eval "$(mise activate bash)"

# Or start a new Fish shell
fish

Automated Dependency Updates with Renovate Bot

This repository uses Renovate Bot to automatically keep dependencies up-to-date. Renovate creates pull requests when new versions are available.

What Renovate Updates

1. mise Tool Versions (private_dot_config/mise/config.toml.tmpl)

  • Node.js versions
  • Go versions
  • Bun versions
  • Python/Miniconda versions

2. GitHub Actions (.github/workflows/*.yml)

  • Action versions (e.g., actions/checkout)
  • GitHub-hosted runner versions

3. Binary Tools in install.sh

  • mise version manager
  • fzf (fuzzy finder)
  • delta (git diff viewer)
  • atuin (shell history)
  • just (command runner)
  • kubectx/kubens (Kubernetes tools)
  • duf (disk usage)
  • dust (du alternative)

How It Works

  1. Automated Runs: Renovate app runs automatically on its schedule
  2. Pull Requests: Creates PRs for each dependency update with conventional commits
  3. Auto-merge: Minor and patch updates are auto-merged if tests pass
  4. Major Updates: Require manual review and approval

Configuration

  • Main config: renovate.json
  • Managed by: GitHub Renovate App (no additional setup needed)

For Contributors

If you fork this repo, you'll need to:

  1. Install the Renovate GitHub App on your fork
  2. Renovate will automatically detect the configuration and start creating PRs

Contributing

Feel free to fork and customize for your own use!

Tool Versions

Last updated: June 2026

The authoritative version list is private_dot_config/mise/config.toml.tmpl; Renovate keeps it current. CLI tools track latest, so only the pinned language runtimes are listed here.

Core Tools

  • chezmoi: latest from official installer
  • mise: latest

Programming Languages (pinned via mise)

Node.js, Python (miniconda3), Go, Bun, and Java (Eclipse Temurin LTS) — exact pinned versions live in private_dot_config/mise/config.toml.tmpl, the source of truth, and are bumped automatically by Renovate.

License

MIT