Consolidate dotfiles improvements (Fish, tmux, CI, deps)#10
Conversation
- Add ~/.bin to Fish PATH for chezmoi-managed scripts - Add nord-dircolors git-repo external with pinned branch - Pin all chezmoi externals via clone --branch for Renovate tracking - Prompt for machine name at chezmoi init (dot_name.tmpl) - Add Fish custom prompts matching zsh/tmux identity layout - Port zsh shell helpers to Fish functions (cdgr, fpr, serve, etc.) - Switch tmux to Catppuccin Macchiato theme - Add chezmoi template validation CI workflow - Add Renovate config and weekly OSV/Homebrew dependency audit - Reconcile README with actual layout and new features Note: archive-type externals conflict with vim/zsh/shell symlink layout, so externals remain git-repo with explicit branch pins. Co-authored-by: Huy Pham <hdp617@users.noreply.github.com>
There was a problem hiding this comment.
Code Review
This pull request introduces a custom machine name configuration prompted during initialization, pins external plugins in .chezmoiexternal.toml with Renovate dependency monitoring, updates the tmux configuration to use the Catppuccin Macchiato theme, and adds several modular Fish shell helper functions and prompts. Feedback focuses on optimizing Fish prompt performance by avoiding external command spawning (such as id -u, whoami, and cat), caching the machine name, correcting path precedence in fish_add_path, replacing non-standard git commands, and adding robust argument validation and force-fetch support to the new shell functions.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| fish_add_path -g -p $HOME/.bin | ||
| fish_add_path -g -p $HOME/.local/bin | ||
| fish_add_path -g -p $HOME/bin No newline at end of file |
There was a problem hiding this comment.
In Fish shell, calling fish_add_path -p sequentially prepends each path to the front of the list one by one. This means that the last path prepended ($HOME/bin) will end up at the very front of your PATH, while the first one prepended ($HOME/.bin) will end up behind the others.
To ensure that $HOME/.bin has the highest precedence (as intended for the chezmoi dot_bin scripts), you should pass all paths to a single fish_add_path invocation in the desired order.
fish_add_path -g -p $HOME/.bin $HOME/.local/bin $HOME/bin
| if test (id -u) -eq 0 | ||
| echo -n (set_color red)'>'(set_color normal)' ' | ||
| else | ||
| echo -n (set_color magenta)'>'(set_color normal)' ' | ||
| end |
There was a problem hiding this comment.
Calling the external command (id -u) on every prompt render spawns a subshell and an external process, which can introduce noticeable prompt lag (especially on macOS or WSL).
Fish provides a built-in fish_is_root_user function that is much faster and more idiomatic.
if fish_is_root_user
echo -n (set_color red)'>'(set_color normal)' '
else
echo -n (set_color magenta)'>'(set_color normal)' '
end
| if test (id -u) -eq 0 | ||
| echo -n (set_color red)(whoami)(set_color normal) | ||
| else | ||
| echo -n (set_color magenta)(whoami)(set_color normal) | ||
| end |
There was a problem hiding this comment.
Avoid calling external commands like (id -u) and (whoami) on every prompt render, as spawning external processes on the hot path of prompt rendering causes lag.
Instead, use the built-in fish_is_root_user function and the standard $USER environment variable.
if fish_is_root_user
echo -n (set_color red)$USER(set_color normal)
else
echo -n (set_color magenta)$USER(set_color normal)
end
| function _machine_name | ||
| if test -f $HOME/.name | ||
| cat $HOME/.name | ||
| else | ||
| hostname -s | ||
| end | ||
| end |
There was a problem hiding this comment.
Since _machine_name is called by fish_right_prompt on every single prompt render, executing cat or hostname -s every time spawns unnecessary external processes and slows down the shell.
We can cache the resolved machine name in a global variable so that it is only computed once per shell session.
function _machine_name
if not set -q _cached_machine_name
if test -f $HOME/.name
set -g _cached_machine_name (cat $HOME/.name)
else
set -g _cached_machine_name (hostname -s)
end
end
echo $_cached_machine_name
end
| function cdgr | ||
| cd (git root) | ||
| end |
There was a problem hiding this comment.
git root is not a standard git command and relies on a custom global git alias being configured. If this alias is missing on a fresh machine, cdgr will fail.
It is more robust and self-contained to use the standard git rev-parse --show-toplevel command directly.
function cdgr
cd (git rev-parse --show-toplevel)
end
| return 1 | ||
| end | ||
|
|
||
| git fetch git@github.com:$user/$repo $branch:$user/$branch |
There was a problem hiding this comment.
If fpr is run multiple times for the same peer branch (e.g., to fetch updates after they force-pushed or rebased), the fetch will fail with a non-fast-forward error.
Prefixing the refspec with + allows force-updating the local reference to match the remote branch.
git fetch git@github.com:$user/$repo +$branch:$user/$branch
| # Machine name for status bar (resolved once when config is sourced) | ||
| set -g @machine_name "#(if [ -f $HOME/.name ]; then cat $HOME/.name; else hostname -s; fi)" |
There was a problem hiding this comment.
In tmux, #(...) in status settings is evaluated periodically (every status-interval seconds), not once when the configuration is sourced. This means tmux will repeatedly spawn shell processes to check for ~/.name and run hostname.
To actually resolve this once when the configuration is sourced (as the comment intends), use run-shell to set the option dynamically.
# Machine name for status bar (resolved once when config is sourced)
run-shell 'tmux set -g @machine_name "$(if [ -f $HOME/.name ]; then cat $HOME/.name; else hostname -s; fi)"'
| function nonascii | ||
| env LC_ALL=C grep -n '[^[:print:][:space:]]' $argv[1] | ||
| end |
There was a problem hiding this comment.
Using $argv[1] limits this function to scanning only the first argument and ignores any subsequent files passed.
Using $argv instead allows scanning multiple files at once, or reading from standard input if no arguments are provided.
function nonascii
env LC_ALL=C grep -n '[^[:print:][:space:]]' $argv
end
| function jump | ||
| cd (dirname $argv[1]) | ||
| end |
There was a problem hiding this comment.
| function xin | ||
| cd $argv[1]; or return | ||
| set -e argv[1] | ||
| command $argv | ||
| end |
There was a problem hiding this comment.
If xin is called with fewer than two arguments (e.g., no directory or no command), it will either change directory to $HOME or fail with empty command execution.
Adding a guard check ensures that both a target directory and a command are provided.
function xin
if test (count $argv) -lt 2
echo "Usage: xin <directory> <command> [args...]" >&2
return 1
end
cd $argv[1]; or return
set -e argv[1]
command $argv
end
lightline.vim and material.vim have no release tags; pin to master/main instead of commit SHAs so git clone --branch works in CI and chezmoi apply. Install chezmoi from GitHub releases with retries instead of get.chezmoi.io to avoid intermittent 504 errors. Co-authored-by: Huy Pham <hdp617@users.noreply.github.com>
Prune test-fixtures before scanning to avoid vim-go stdlib noise. Treat osv-scanner exit 128 (no package sources) as success. Co-authored-by: Huy Pham <hdp617@users.noreply.github.com>
Summary
Consolidates the planned dotfiles improvements from the earlier draft PRs into a single branch. Fish is brought closer to zsh parity, tmux matches the Catppuccin stack, chezmoi init prompts for a machine name, and CI/dependency monitoring is added.
Changes
Fish shell
~/.binin00-path.fish.tmpl(chezmoidot_bin/scripts)fish_prompt/fish_right_promptaligned with zsh/tmux (USER at <~/.name>+fish_git_prompt)~/.shell/aliases.sh:cdgr,fpr,serve,jump,xin,nonascii,syspip/syspip3Chezmoi / machine identity
machine_nameat init (default: hostname); templatedot_name.tmplfrom that valuegit-repoexternals viaclone.args = ["--branch", …]for Renovate trackingTmux
~/.nameonce into@machine_namewhen config is sourcedCI & dependency monitoring
.github/workflows/chezmoi.yml— render all*.tmplandchezmoi apply --dry-run.github/renovate.json— bump pinned externals, Homebrew bundle, and GitHub Actions.github/workflows/dependency-audit.yml— weekly OSV scan of pinned externals + macOS Homebrew outdated reportDocs
Test plan
*.tmplrender with test[data]includingmachine_namechezmoi apply --exclude externalsdeploys dotfiles correctlydot_config/fish/**/*.fishv0.2.0and providessrc/dir_colorschezmoi initon a fresh machine prompts for machine namewhich tmxresolves to~/.bin/tmxSupersedes
This PR consolidates draft PRs #1–#9. After merge, those draft branches can be closed.