Skip to content

Refactor dotfiles for cross-platform support and add fzf utilities#1

Open
jhwheeler wants to merge 7 commits intomasterfrom
claude/cleanup-dotfiles-aCFyi
Open

Refactor dotfiles for cross-platform support and add fzf utilities#1
jhwheeler wants to merge 7 commits intomasterfrom
claude/cleanup-dotfiles-aCFyi

Conversation

@jhwheeler
Copy link
Copy Markdown
Owner

Summary

This PR refactors the dotfiles configuration to support both macOS and Linux systems, adds a collection of fzf-based utility functions, and removes hardcoded paths in favor of environment variables. It also includes cleanup of unused tools and configuration.

Key Changes

Cross-Platform Support

  • Added OS detection in shell/common/env to set DOTFILES_OS variable (linux/macos)
  • Moved platform-specific configurations (Android SDK, pnpm, Bash deprecation warning) into conditional blocks based on detected OS
  • Updated shell/zsh/zshrc to handle powerlevel10k theme installation paths for both macOS (Homebrew) and Linux (Arch)
  • Made clipboard aliases (pbcopy/pbpaste) conditional for Linux only
  • Added macOS-only aliases for Homebrew commands

Path Hardcoding Fixes

  • Replaced hardcoded /Users/jackson paths with $HOME throughout:
    • shell/common/env: SCM Breeze, Deno, gitconfig
    • shell/zsh/zshrc: oh-my-zsh installation path
    • fzf/fzf.bash and fzf/fzf.zsh: FZF binary paths
    • git/gitconfig: global gitignore path
  • Updated project paths from ~/Projects to ~/projects (lowercase)

New fzf Utility Functions

Added several interactive fzf-based helper functions to shell/bash/bashrc:

  • fe: Open files with default editor via fuzzy finder
  • fcd/fcda: Change directory with fuzzy finder (with/without hidden dirs)
  • cds: Change to directory of selected file
  • fcb: Git commit browser with preview
  • fgst: Interactive git stash manager with diff/branch checkout
  • fbr: Git branch checkout with fuzzy finder
  • fcoc: Git commit checkout
  • fta: Tmux session attach with fuzzy finder

Configuration Cleanup

  • Removed unused tools from Brewfile (ack, bit, cmatrix, ctags, hub, imagemagick, mas, maven, mutt, pandoc, redis, watson, yarn, etc.)
  • Removed hardcoded Lynx, Android, and Watson aliases
  • Removed duplicate alias definitions
  • Removed TODO comment about cursor in vim mode
  • Added .gitignore for state files and secrets
  • Cleaned up tmux status bar (removed battery/Spotify plugins, simplified display)

New Features

  • Added Atuin shell history integration to both bash and zsh
  • Added Claude Code hook configuration for notifications
  • Added Hyprland auto-start on TTY1 for Arch Linux
  • Added Wayland environment variable support to tmux
  • Added Rust/Cargo to PATH in shell/common/env

Minor Improvements

  • Fixed Python3 path detection in vim plugins (use exepath() instead of hardcoded path)
  • Updated tmux config comments and unbind C-b explicitly
  • Improved bash_profile structure with better comments
  • Made FZF configuration more robust with better filtering options

https://claude.ai/code/session_01RtJ89RVipBb4fp1XBbo4Wm

- Replace all hardcoded /Users/jackson/ paths with $HOME
- Add OS detection (DOTFILES_OS) in shell/common/env
- Platform-conditional config for pnpm, powerlevel10k, clipboard, Hyprland
- Remove orphaned aliases (watson, lynx, howdoi, vifm, brewup)
- Remove deprecated packages from Brewfile (spotify-tui, skype, etc.)
- Fix undefined $GLOBALINSTALLDIR in vim plugins
- Remove osxkeychain credential helper from gitconfig
- Add fzf helper functions from arch branch (fe, fcd, fcb, fbr, etc.)
- Add atuin shell history support
- Add Wayland env vars to tmux.conf
- Add Claude Code config (notify hook)
- Add .gitignore for state files and secrets

https://claude.ai/code/session_01RtJ89RVipBb4fp1XBbo4Wm
Source ~/.shell/secrets early in env if it exists. The file is created
by dotbot install but gitignored, so API keys and tokens stay local
to each machine and never touch git.

https://claude.ai/code/session_01RtJ89RVipBb4fp1XBbo4Wm
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the dotfiles repo toward cross-platform (macOS/Linux) support by removing user-specific paths, adding OS-aware config blocks, and introducing fzf-based shell utilities plus Claude Code notification hooks.

Changes:

  • Add OS detection (DOTFILES_OS) and move platform-specific PATH/config into macOS/Linux conditionals.
  • Replace hardcoded /Users/... paths with $HOME and normalize ~/Projects~/projects.
  • Add fzf-based navigation/git/tmux helper functions and integrate Atuin history + Claude Code hooks.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
vim/plugins.vim Uses exepath('python3') and updates Startify bookmarks to lowercase ~/projects.
tmux.conf Tweaks prefix handling, simplifies status-right, and adds Wayland env propagation.
shell/zsh/zshrc Removes hardcoded oh-my-zsh path; adds OS-aware powerlevel10k sourcing and Atuin init.
shell/common/env Adds OS detection and splits platform-specific Android/pnpm/bash config by OS.
shell/common/aliases Makes clipboard aliases OS-aware; updates paths and prunes old aliases.
shell/bash/bashrc Adds multiple fzf-based helper functions (files/dirs/git/tmux).
shell/bash/bash_profile Improves structure; adds Atuin env and optional Hyprland autostart on TTY1.
install.conf.yaml Adds Claude config symlinks and directory creation; removes Brewfile linking.
git/gitconfig Removes hardcoded global gitignore path.
fzf/fzf.zsh Replaces hardcoded fzf paths with $HOME.
fzf/fzf.bash Replaces hardcoded fzf paths with $HOME.
claude/settings.json Adds Claude hook configuration to run a notification script.
claude/hooks/notify.sh Adds Linux notification hook implementation.
brew/Brewfile Cleans up taps/packages; keeps a smaller core toolset.
.gitignore Adds ignores for state files and common secret/env files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +62 to +70
dir=$(fd . "${1:-.}" --type=d | fzf --no-multi --layout=reverse --height=40%) &&
cd "$dir"
}

# fcda - including hidden directories
function fcda {
local dir
dir=$(fd . "${1:-.}" --hidden --type=d | fzf --no-multi --layout=reverse --height=40%) &&
cd "$dir"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fcd relies on the external fd command, but the macOS Brewfile in this repo doesn’t install fd. To keep this helper usable after install, either add fd to brew/Brewfile (and document the Linux package) or provide a fallback using find when fd isn’t available.

Suggested change
dir=$(fd . "${1:-.}" --type=d | fzf --no-multi --layout=reverse --height=40%) &&
cd "$dir"
}
# fcda - including hidden directories
function fcda {
local dir
dir=$(fd . "${1:-.}" --hidden --type=d | fzf --no-multi --layout=reverse --height=40%) &&
cd "$dir"
if command -v fd >/dev/null 2>&1; then
dir=$(fd . "${1:-.}" --type=d | fzf --no-multi --layout=reverse --height=40%)
else
dir=$(find "${1:-.}" -type d 2>/dev/null | fzf --no-multi --layout=reverse --height=40%)
fi
[ -n "$dir" ] && cd "$dir"
}
# fcda - including hidden directories
function fcda {
local dir
if command -v fd >/dev/null 2>&1; then
dir=$(fd . "${1:-.}" --hidden --type=d | fzf --no-multi --layout=reverse --height=40%)
else
dir=$(find "${1:-.}" -type d 2>/dev/null | fzf --no-multi --layout=reverse --height=40%)
fi
[ -n "$dir" ] && cd "$dir"

Copilot uses AI. Check for mistakes.
Comment on lines +5 to +8
# List contents with colors for file types, (A)lmost all hidden files (without . and ..), in (C)olumns, with class indicators (F)
alias ls='ls -ACFG'
alias ls='ls -ACF'
# List contents with colors for file types, (a)ll hidden entries (including . and ..), use (l)ong listing format, with class indicators (F)
alias ll='ls -alFG'
alias ll='ls -alF'
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ls/ll alias comments say they list contents “with colors”, but the updated flags (-ACF / -alF) no longer enable colored output on either macOS (-G) or GNU (--color=auto). Update the comment or add a platform-aware color flag so behavior matches the description.

Copilot uses AI. Check for mistakes.
- [touch ~/.shell/secrets, Creating local secrets file (not tracked by git)]
- [mkdir -p ~/.claude/hooks, Creating Claude Code config directory]
# If you haven't already, run prefix-I with tmux open after doing this to reload tmux and install the plugins
- [ if test -d "~/.tmux/plugins/tpm"; then git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm; fi ]
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The TPM install command won’t work on a fresh setup: it uses test -d "~/.tmux/plugins/tpm" (quoted ~ won’t expand, so the test is always false) and it only runs git clone when the directory exists. Remove the quotes around ~ (or use $HOME) and invert the condition so cloning happens only when TPM is missing.

Suggested change
- [ if test -d "~/.tmux/plugins/tpm"; then git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm; fi ]
- [ if [ ! -d "$HOME/.tmux/plugins/tpm" ]; then git clone https://github.com/tmux-plugins/tpm "$HOME/.tmux/plugins/tpm"; fi ]

Copilot uses AI. Check for mistakes.
@@ -7,9 +7,6 @@
- link:
~/.dotfiles: ''

Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the ~/Brewfile link changes the default brew bundle workflow (it looks for ~/Brewfile unless --file is provided). If the intended setup still expects brew bundle to work without extra flags, consider keeping the symlink or documenting the new --file brew/Brewfile usage.

Suggested change
# Homebrew
~/Brewfile: brew/Brewfile

Copilot uses AI. Check for mistakes.
local branches branch
branches=$(git branch --all | grep -v HEAD) &&
branch=$(echo "$branches" |
fzf --delimiter=$(( 2 + $(wc -l <<< "$branches") )) --no-multi --layout=reverse --height=40%) &&
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fbr passes a numeric expression to fzf --delimiter, but --delimiter expects a delimiter pattern/string, not a column index. This can cause fzf field-splitting to behave unpredictably; drop --delimiter here or set it to an actual delimiter that matches the branch output format.

Suggested change
fzf --delimiter=$(( 2 + $(wc -l <<< "$branches") )) --no-multi --layout=reverse --height=40%) &&
fzf --no-multi --layout=reverse --height=40%) &&

Copilot uses AI. Check for mistakes.

# Config
export DOTFILES="~/Projects/dotfiles"
export DOTFILES="$HOME/projects/dotfiles"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DOTFILES is exported as $HOME/projects/dotfiles, but the installer links the repo to ~/.dotfiles (and alias dotfiles also points there). This makes the editor aliases (vimrc, bashrc, etc.) location-dependent and likely broken unless the repo is cloned to exactly ~/projects/dotfiles; consider pointing DOTFILES at ~/.dotfiles (or deriving it from the symlink) to match the install layout.

Suggested change
export DOTFILES="$HOME/projects/dotfiles"
export DOTFILES="$HOME/.dotfiles"

Copilot uses AI. Check for mistakes.

# Miscellaneous Shortcuts
alias c="clear"
alias cdl="cd $1 && ls"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alias cdl="cd $1 && ls" won’t work as intended because shell aliases don’t take positional parameters; $1 will typically expand to empty, causing cd to run with no target. Use a shell function (or a script) so the target directory argument is actually passed at invocation time.

Suggested change
alias cdl="cd $1 && ls"
cdl() {
cd "$1" && ls
}

Copilot uses AI. Check for mistakes.
Comment on lines +98 to +108
local out q k sha
while out=$(
git stash list --pretty="%C(yellow)%h %>(14)%Cgreen%cr %C(blue)%gs" |
fzf --ansi --no-sort --query="$q" --print-query \
--expect=ctrl-d,ctrl-b);
do
mapfile -t out <<< "$out"
q="${out[0]}"
k="${out[1]}"
sha="${out[-1]}"
sha="${sha%% *}"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fgst uses mapfile, which is not available in the default macOS /bin/bash (3.2). Since this repo targets macOS + Linux, consider rewriting this parsing to avoid mapfile (e.g., using a while IFS= read -r loop) or gating these helpers behind a Bash version check.

Suggested change
local out q k sha
while out=$(
git stash list --pretty="%C(yellow)%h %>(14)%Cgreen%cr %C(blue)%gs" |
fzf --ansi --no-sort --query="$q" --print-query \
--expect=ctrl-d,ctrl-b);
do
mapfile -t out <<< "$out"
q="${out[0]}"
k="${out[1]}"
sha="${out[-1]}"
sha="${sha%% *}"
local out q k sha sha_line
while out=$(
git stash list --pretty="%C(yellow)%h %>(14)%Cgreen%cr %C(blue)%gs" |
fzf --ansi --no-sort --query="$q" --print-query \
--expect=ctrl-d,ctrl-b);
do
IFS=$'\n' read -r q k sha_line <<< "$out"
sha="${sha_line%% *}"

Copilot uses AI. Check for mistakes.
Comment on lines +142 to +143
fzf --layout=reverse --height=20% --query="$1" --select-1 --exit-0) &&
tmux -CC attach -d -t "$session"
Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fta uses tmux -CC attach ..., which enables tmux control mode intended for iTerm2 integration and will behave poorly in most terminals (and on Linux). Consider using a normal tmux attach by default and only using -CC when iTerm2 is detected (or via an explicit opt-in env var/flag).

Suggested change
fzf --layout=reverse --height=20% --query="$1" --select-1 --exit-0) &&
tmux -CC attach -d -t "$session"
fzf --layout=reverse --height=20% --query="$1" --select-1 --exit-0) || return
# Use tmux control mode (-CC) only when appropriate:
# - TERM_PROGRAM=iTerm.app (iTerm2 integration), or
# - explicit opt-in via FTA_TMUX_CC environment variable.
if [[ "$TERM_PROGRAM" == "iTerm.app" || -n "$FTA_TMUX_CC" ]]; then
tmux -CC attach -d -t "$session"
else
tmux attach -d -t "$session"
fi

Copilot uses AI. Check for mistakes.
Comment on lines +2 to +6
INPUT=$(cat)
TITLE=$(printf '%s' "$INPUT" | jq -r '.title // "Claude Code"')
MESSAGE=$(printf '%s' "$INPUT" | jq -r '.message // "Needs attention"')
TYPE=$(printf '%s' "$INPUT" | jq -r '.notification_type // "unknown"')

Copy link

Copilot AI Feb 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

notify.sh hard-depends on jq, notify-send, and pw-play, but none of these are ensured by the macOS Brewfile (and notify-send/pw-play are Linux-specific). Add dependency installation docs or make the script degrade gracefully (e.g., check command -v and no-op / choose a macOS notifier when unavailable) to avoid hook failures.

Copilot uses AI. Check for mistakes.
jhwheeler and others added 5 commits February 17, 2026 14:05
Fix bugs: notify.sh no-op case branches, tmux C-j `&` vs `&&`, tpm
clone inverted condition, cdl alias $1 expansion. Fix issues: restore
ls colors per-platform, expand tmux PATH for Linux, add fd to Brewfile,
quote $1 in take(), add atuin init for bash, prevent p10k double-load,
fix gitconfig mixed indent, remove extra space in FZF config.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Quote $HOME in fzf PATH glob checks to handle spaces
- Use readarray instead of unquoted array assignment in fe()
- Quote $sha and command substitutions in fgst, fbr, fcoc
- Remove -CC (iTerm2 control mode) from fta for cross-platform compat
- Use dotbot create directive for directories instead of shell mkdir
- Normalize ~ to $HOME in PATH entries for consistency

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Guard tmux auto-attach to interactive shells only, add PATH dedup
helpers to prevent duplicates in nested shells, use bat explicitly
in FZF preview with fallback, add fd guards to fcd/fcda, create
zprofile for shell-agnostic Hyprland auto-start, remove hardcoded
tmux PATH override, and add gitconfig local include for
platform-specific config like credential helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move fzf helpers to shell/common/functions for both bash and zsh,
extract login tasks (atuin env, Hyprland) to shell/common/login,
move tmux auto-attach to end of env, add p10k fallback warning,
move gitconfig [include] to EOF for proper override semantics,
fix commit hash grep pattern, and disown background pw-play.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants