Skip to content

alechemy/dotfiles-fish

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

517 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

.dotfiles

Personal dotfiles for macOS, managed with GNU Stow.

Component Tool
Shell Fish
Package manager Homebrew
Dotfile manager GNU Stow
Runtime manager Mise
Terminal Ghostty
Prompt Starship
Editor Zed
Window management AeroSpace
Keyboard Karabiner-Elements

Quick Start

For a fresh Mac, follow MIGRATION.md instead of the snippet below. The build scripts require an authenticated 1Password CLI session, DEVONthink installed, and a few other prerequisites that setup.sh does not bootstrap on its own.

git clone https://github.com/alechemy/dotfiles-fish.git ~/.dotfiles
cd ~/.dotfiles
./scripts/setup.sh

This installs Homebrew + all dependencies from Brewfile, builds generated configs (injecting secrets via 1Password CLI), symlinks the stow packages to $HOME (DEVONthink and streamrip are opt-in prompts), and sets Fish as the default shell.

Structure

.dotfiles/
β”œβ”€β”€ Brewfile                 # Homebrew dependencies
β”œβ”€β”€ homebrew/                # Local-only tap (casks with no upstream cask)
β”œβ”€β”€ devonthink/              # DEVONthink pipeline docs
β”œβ”€β”€ drafts/                  # Drafts action scripts (repo is canonical)
β”œβ”€β”€ keyboard-maestro/        # Scripts referenced by KM macros
β”œβ”€β”€ hrm/                     # Glove80 keyboard layout + README
β”œβ”€β”€ firmware/                # Keyboard/device firmware + layouts
β”‚   β”œβ”€β”€ ploopy-knob/         # Ploopy Knob QMK keymap + build recipe
β”‚   └── tailorkey/           # Glove80/Go60 TailorKey layouts
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ setup.sh                  # Main bootstrap script
β”‚   β”œβ”€β”€ restow-changed.sh         # Auto-restow worker (git post-merge/-rewrite/-commit hooks)
β”‚   β”œβ”€β”€ git-hooks/                # Tracked hooks wired via core.hooksPath
β”‚   β”œβ”€β”€ build-zed-config.sh       # Inject 1Password secrets into Zed config
β”‚   β”œβ”€β”€ build-streamrip-config.sh # Inject 1Password secrets into streamrip config
β”‚   β”œβ”€β”€ build-context7-config.sh  # op read β†’ fish conf.d Context7 key export
β”‚   β”œβ”€β”€ build-things-config.sh    # op read β†’ ~/.zshenv Things auth token
β”‚   β”œβ”€β”€ build-vscode-config.sh    # Expand ${HOME} in VSCodium settings.json
β”‚   β”œβ”€β”€ build-launchd-plists.sh   # Expand __HOME__ in launch-agent plist templates
β”‚   β”œβ”€β”€ lint-launchd-plists.sh    # Enforce TCC-stable interpreters in launch agents
β”‚   β”œβ”€β”€ seed-devonthink-config.sh # Copy-if-absent DEVONthink seed plists
β”‚   β”œβ”€β”€ setup-vscode.sh           # VSCodium extension install
β”‚   β”œβ”€β”€ aerospace-*.sh|py         # AeroSpace gap/window helpers
β”‚   └── macos.sh                  # macOS system defaults
β”œβ”€β”€ stow/                    # Stow packages (auto-linked by setup.sh; devonthink + streamrip opt-in)
β”‚   β”œβ”€β”€ aerospace/           # Tiling window manager
β”‚   β”œβ”€β”€ bin/                 # ~/.local/bin scripts
β”‚   β”œβ”€β”€ borders/             # JankyBorders window borders
β”‚   β”œβ”€β”€ chromium-bookmarks/  # Chromium β†’ Safari bookmark bridge for Alfred
β”‚   β”œβ”€β”€ claude/              # Claude Code global config, skills, hooks
β”‚   β”œβ”€β”€ copilot/             # Copilot CLI config
β”‚   β”œβ”€β”€ devonthink/          # DEVONthink automation (opt-in)
β”‚   β”œβ”€β”€ dropzone/            # Dropzone action bundles
β”‚   β”œβ”€β”€ editorconfig/        # ~/.editorconfig
β”‚   β”œβ”€β”€ espanso/             # Text expansion
β”‚   β”œβ”€β”€ fish/                # Fish shell config, functions, plugins
β”‚   β”œβ”€β”€ ghostty/             # Terminal emulator
β”‚   β”œβ”€β”€ git/                 # Git config + global excludes
β”‚   β”œβ”€β”€ karabiner/           # Keyboard remapping (goku EDN source)
β”‚   β”œβ”€β”€ linearmouse/         # Ploopy Knob scroll config (seeded, not stowed)
β”‚   β”œβ”€β”€ mise/                # Runtime version manager
β”‚   β”œβ”€β”€ nas-mount/           # Auto-mount NAS SMB shares (launch agent)
β”‚   β”œβ”€β”€ navidrome/           # Navidrome client env
β”‚   β”œβ”€β”€ sketchybar/          # Menu bar
β”‚   β”œβ”€β”€ ssh/                 # SSH client config
β”‚   β”œβ”€β”€ starship/            # Shell prompt theme
β”‚   β”œβ”€β”€ streamrip/           # Music downloader config (opt-in, op inject)
β”‚   β”œβ”€β”€ tmux/                # Phone-friendly tmux config
β”‚   β”œβ”€β”€ vscode/              # VSCodium settings (${HOME} expansion)
β”‚   └── zed/                 # Zed editor (1Password op inject)
β”œβ”€β”€ stow-work/               # Work config (gitignored; auto-stowed when populated by file-copy)
└── stow-local/              # Machine-local config (gitignored)

Each directory under stow/ mirrors the path relative to $HOME. Stow creates symlinks from $HOME back into this repo. Editing stowed files requires no action since symlinks already point here -- only restow when adding or removing files.

Runtimes (mise)

Language runtimes and globally-installed CLIs are declared in stow/mise/.config/mise/config.toml. Running mise install on a fresh machine reproduces everything listed there.

mise use -g node@lts             # add/pin a runtime globally
mise use -g npm:defuddle         # add a global npm CLI (survives node upgrades)
mise up                          # update all tools to latest matching versions
mise up npm:defuddle             # update a single tool
mise ls                          # list everything mise manages
mise uninstall <tool>            # remove from disk
mise unuse -g <tool>             # remove the declaration from config.toml

mise use/mise unuse edit config.toml in place, so the dotfiles repo stays in sync. Prefer the npm:<pkg> backend over raw npm install -g so globals get reinstalled against whichever node version is active.

Generated configs (template β†’ build β†’ stow)

Some configs are generated from a tracked template at install time. Three flavors:

  • 1Password secret injection (stow/zed/, stow/streamrip/): the template has op://Vault/Item/Field references which op inject resolves into the real config (gitignored). Both also do ${HOME} expansion.
  • 1Password single-value fetch (build-context7-config.sh β†’ fish conf.d Context7 key; build-things-config.sh β†’ ~/.zshenv Things token): op read fetches one secret and the script writes the output directly β€” no template file, used where a template sibling would be harmful (fish auto-sources everything in conf.d) or the output lives outside the stow tree.
  • Path expansion only (stow/vscode/): the template has ${HOME} placeholders that get expanded into absolute paths. Used where the target tool requires absolute paths and doesn't honor its own variable substitution (e.g., be5invis.vscode-custom-css reads file:// URIs literally).

Each follows the same pattern: tracked *.template.{json,toml}, generated output gitignored, build script run before stow, and a .stow-local-ignore entry that excludes the template from being symlinked. See scripts/build-zed-config.sh as the canonical example.

Work Config

stow-work/ holds work-specific config (fish functions, sketchybar overlays, Copilot/Atlassian MCP setup, docs). It is gitignored apart from .gitkeep, so a fresh clone leaves it empty and nothing links. On a work machine, populate it by file-copy from another machine β€” setup.sh auto-stows it once it has content. To link without a full setup re-run:

cd ~/.dotfiles/stow-work
stow --restow --no-folding --ignore='.DS_Store' --ignore='__pycache__' --target="$HOME" work

About

My dotfiles for fish shell. 🐑 🐚

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors