From a44f9b751011445a72ebd708569fa83c128ef539 Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 08:29:16 -0600 Subject: [PATCH 1/6] chore(tool-versions): remove Python tool version Remove the pinned Python entry from the asdf tool versions file and normalize spacing in the remaining tool declarations. This keeps the shared tool list focused on tools managed by the dotfiles. --- dot_tool-versions | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/dot_tool-versions b/dot_tool-versions index 3b7ac9f..4593d24 100644 --- a/dot_tool-versions +++ b/dot_tool-versions @@ -1,8 +1,7 @@ -dart 2.19.6 -java corretto-21.0.2.13.1 -python 3.13.0 +dart 2.19.6 +java corretto-21.0.2.13.1 golang latest nodejs 18.20.8 -maven 3.9.11 -pnpm latest -vale latest +maven 3.9.11 +pnpm latest +vale latest From ea94720e88bcec8a0f384d460e42f78b96edc315 Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 08:36:21 -0600 Subject: [PATCH 2/6] feat(shell): add eza-backed directory listing aliases Add shared profile.d aliases (ls, ll, la, lla, lt, lS) gated on eza being on PATH so bash and zsh share the same directory listing UX. Install eza via Homebrew on macOS. Verify: chezmoi apply && source ~/.config/chezmoi/profile.d/eza-aliases.sh && alias ll --- Brewfile | 2 ++ dot_config/chezmoi/profile.d/eza-aliases.sh | 10 ++++++++++ 2 files changed, 12 insertions(+) create mode 100644 dot_config/chezmoi/profile.d/eza-aliases.sh diff --git a/Brewfile b/Brewfile index d38d3d4..bae78ec 100644 --- a/Brewfile +++ b/Brewfile @@ -91,6 +91,8 @@ brew "ctags" brew "diffutils" # Activates NFS on docker-machine brew "docker-machine-nfs" +# Modern replacement for ls with git integration and icons +brew "eza" # Image processing and image analysis library brew "leptonica" # Subtitle renderer for the ASS/SSA subtitle format diff --git a/dot_config/chezmoi/profile.d/eza-aliases.sh b/dot_config/chezmoi/profile.d/eza-aliases.sh new file mode 100644 index 0000000..b780589 --- /dev/null +++ b/dot_config/chezmoi/profile.d/eza-aliases.sh @@ -0,0 +1,10 @@ +# Directory listing aliases backed by eza (https://github.com/eza-community/eza). +if command -v eza >/dev/null 2>&1; then + alias ls='eza --color=auto --group-directories-first --icons=auto' + alias l='eza --color=auto --group-directories-first --icons=auto' + alias ll='eza -l --color=auto --group-directories-first --icons=auto --git' + alias la='eza -a --color=auto --group-directories-first --icons=auto' + alias lla='eza -la --color=auto --group-directories-first --icons=auto --git' + alias lt='eza --tree --color=auto --group-directories-first --icons=auto' + alias lS='eza -l --sort=size --color=auto --group-directories-first --icons=auto' +fi From 4f269b50e42e6b8b45ccf420a43177592a2b26de Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 09:21:30 -0600 Subject: [PATCH 3/6] feat(shell): replace cd with zoxide in human shells Move zoxide init into shared profile.d and use --cmd cd for bash and zsh. Skip zoxide in agent subprocesses (CURSOR_AGENT, CLAUDECODE=1, CUSTOM_AGENT_SHELL) so they keep builtin cd and avoid database noise. Add zoxide to the Brewfile. Verify: chezmoi apply && type cd --- Brewfile | 2 ++ dot_bash_profile.tmpl | 3 --- .../chezmoi/profile.d/zoxide-init.sh.tmpl | 27 +++++++++++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl diff --git a/Brewfile b/Brewfile index bae78ec..c1eca77 100644 --- a/Brewfile +++ b/Brewfile @@ -261,6 +261,8 @@ brew "wxwidgets" brew "yarn" # Process YAML, JSON, XML, CSV and properties documents from the CLI brew "yq" +# Smarter cd command (jump to frecent directories) +brew "zoxide" # Kubernetes CLI To Manage Your Clusters In Style! brew "derailed/k9s/k9s" # Vault diff --git a/dot_bash_profile.tmpl b/dot_bash_profile.tmpl index 9f501bd..d104dc2 100644 --- a/dot_bash_profile.tmpl +++ b/dot_bash_profile.tmpl @@ -114,9 +114,6 @@ if [ -z "$INTELLIJ_ENVIRONMENT_READER" ] && command -v mise >/dev/null 2>&1; the export __MISE_EXE fi fi -if [ -z "$INTELLIJ_ENVIRONMENT_READER" ] && command -v zoxide >/dev/null 2>&1; then - eval "$(zoxide init bash)" -fi {{- end }} # HACK: to get conda 4.7.5 working again diff --git a/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl new file mode 100644 index 0000000..df333b0 --- /dev/null +++ b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl @@ -0,0 +1,27 @@ +{{- if ne .chezmoi.os "windows" }} +# zoxide: replace cd with smart jumps in human shells. Agent subprocesses keep +# builtin cd and do not write to the zoxide database. + +_is_agent_shell() { + # Cursor IDE / CLI agent (https://cursor.com/docs/agent/tools/terminal) + [ -n "${CURSOR_AGENT:-}" ] && return 0 + # Claude Code bash tool / hooks (https://code.claude.com/docs/en/env-vars) + [ "${CLAUDECODE:-}" = "1" ] && return 0 + # Explicit opt-in for other agent shells (e.g. OpenCode bash tool via + # opencode.json "env": { "CUSTOM_AGENT_SHELL": "1" }) + [ -n "${CUSTOM_AGENT_SHELL:-}" ] && return 0 + return 1 +} + +if [ -z "${INTELLIJ_ENVIRONMENT_READER:-}" ] && command -v zoxide >/dev/null 2>&1; then + if _is_agent_shell; then + : + elif [ -n "${ZSH_VERSION:-}" ]; then + eval "$(zoxide init zsh --cmd cd)" + else + eval "$(zoxide init bash --cmd cd)" + fi +fi + +unset -f _is_agent_shell 2>/dev/null || true +{{- end }} From 8c2a8ee45050114f31d414bf25e55e5273d4ffa3 Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 09:21:30 -0600 Subject: [PATCH 4/6] fix(shell): source profile.d before mise for agent detection Load profile.d (00-agent-shell.sh, zoxide-init) before mise activate so agent subprocesses skip zoxide while keeping full mise cd hooks for per-directory tool versions. Verify: CURSOR_AGENT=1 bash -lc 'type z' # not found --- dot_bash_profile.tmpl | 18 +++++++++--------- dot_config/chezmoi/profile.d/00-agent-shell.sh | 13 +++++++++++++ .../chezmoi/profile.d/zoxide-init.sh.tmpl | 15 +-------------- dot_zshrc.tmpl | 18 +++++++++--------- 4 files changed, 32 insertions(+), 32 deletions(-) create mode 100644 dot_config/chezmoi/profile.d/00-agent-shell.sh diff --git a/dot_bash_profile.tmpl b/dot_bash_profile.tmpl index d104dc2..8704344 100644 --- a/dot_bash_profile.tmpl +++ b/dot_bash_profile.tmpl @@ -100,6 +100,15 @@ path_append "$HOME/.opencode/bin" export CHEZMOI_GH_TOKEN_OP_REF='{{ if hasKey . "gh" }}{{ .gh.tokenOpRef }}{{ else }}{{ env "CHEZMOI_GH_TOKEN_OP_REF" }}{{ end }}' {{- end }} +if [ -d "$HOME/.config/chezmoi/profile.d" ]; then + for _chez_profile_d in "$HOME"/.config/chezmoi/profile.d/*.sh; do + [ -r "$_chez_profile_d" ] || continue + # shellcheck source=/dev/null + . "$_chez_profile_d" + done + unset _chez_profile_d +fi + {{- if ne .chezmoi.os "windows" }} if [ -z "$INTELLIJ_ENVIRONMENT_READER" ] && command -v mise >/dev/null 2>&1; then eval "$(mise activate bash)" @@ -163,15 +172,6 @@ aprompt () { oprompt "$@" } -if [ -d "$HOME/.config/chezmoi/profile.d" ]; then - for _chez_profile_d in "$HOME"/.config/chezmoi/profile.d/*.sh; do - [ -r "$_chez_profile_d" ] || continue - # shellcheck source=/dev/null - . "$_chez_profile_d" - done - unset _chez_profile_d -fi - ghpersonalauth () { local config_dir config_dir="${CHEZMOI_GH_CONFIG_DIR:-$HOME/.config/gh-personal}" diff --git a/dot_config/chezmoi/profile.d/00-agent-shell.sh b/dot_config/chezmoi/profile.d/00-agent-shell.sh new file mode 100644 index 0000000..b08f5b9 --- /dev/null +++ b/dot_config/chezmoi/profile.d/00-agent-shell.sh @@ -0,0 +1,13 @@ +# Agent subprocess detection for profile.d consumers (e.g. zoxide-init). +# Load first (00- prefix) so later snippets can branch before smart-cd init. + +_is_agent_shell() { + # Cursor IDE / CLI agent (https://cursor.com/docs/agent/tools/terminal) + [ -n "${CURSOR_AGENT:-}" ] && return 0 + # Claude Code bash tool / hooks (https://code.claude.com/docs/en/env-vars) + [ "${CLAUDECODE:-}" = "1" ] && return 0 + # Explicit opt-in for other agent shells (e.g. OpenCode bash tool via + # opencode.json "env": { "CUSTOM_AGENT_SHELL": "1" }) + [ -n "${CUSTOM_AGENT_SHELL:-}" ] && return 0 + return 1 +} diff --git a/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl index df333b0..971850d 100644 --- a/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl +++ b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl @@ -2,19 +2,8 @@ # zoxide: replace cd with smart jumps in human shells. Agent subprocesses keep # builtin cd and do not write to the zoxide database. -_is_agent_shell() { - # Cursor IDE / CLI agent (https://cursor.com/docs/agent/tools/terminal) - [ -n "${CURSOR_AGENT:-}" ] && return 0 - # Claude Code bash tool / hooks (https://code.claude.com/docs/en/env-vars) - [ "${CLAUDECODE:-}" = "1" ] && return 0 - # Explicit opt-in for other agent shells (e.g. OpenCode bash tool via - # opencode.json "env": { "CUSTOM_AGENT_SHELL": "1" }) - [ -n "${CUSTOM_AGENT_SHELL:-}" ] && return 0 - return 1 -} - if [ -z "${INTELLIJ_ENVIRONMENT_READER:-}" ] && command -v zoxide >/dev/null 2>&1; then - if _is_agent_shell; then + if type _is_agent_shell >/dev/null 2>&1 && _is_agent_shell; then : elif [ -n "${ZSH_VERSION:-}" ]; then eval "$(zoxide init zsh --cmd cd)" @@ -22,6 +11,4 @@ if [ -z "${INTELLIJ_ENVIRONMENT_READER:-}" ] && command -v zoxide >/dev/null 2>& eval "$(zoxide init bash --cmd cd)" fi fi - -unset -f _is_agent_shell 2>/dev/null || true {{- end }} diff --git a/dot_zshrc.tmpl b/dot_zshrc.tmpl index 29535a2..995a058 100644 --- a/dot_zshrc.tmpl +++ b/dot_zshrc.tmpl @@ -11,6 +11,15 @@ export AI_TERM_CMD="opencode" export CHEZMOI_GH_TOKEN_OP_REF='{{ if hasKey . "gh" }}{{ .gh.tokenOpRef }}{{ else }}{{ env "CHEZMOI_GH_TOKEN_OP_REF" }}{{ end }}' {{- end }} +if [[ -d "$HOME/.config/chezmoi/profile.d" ]]; then + for _chez_profile_d in "$HOME"/.config/chezmoi/profile.d/*.sh(N); do + [[ -r "$_chez_profile_d" ]] || continue + # shellcheck source=/dev/null + . "$_chez_profile_d" + done + unset _chez_profile_d +fi + {{- if ne .chezmoi.os "windows" }} if command -v mise >/dev/null 2>&1; then eval "$(mise activate zsh)" @@ -54,15 +63,6 @@ aprompt () { oprompt "$@" } -if [[ -d "$HOME/.config/chezmoi/profile.d" ]]; then - for _chez_profile_d in "$HOME"/.config/chezmoi/profile.d/*.sh(N); do - [[ -r "$_chez_profile_d" ]] || continue - # shellcheck source=/dev/null - . "$_chez_profile_d" - done - unset _chez_profile_d -fi - ghpersonalauth () { local config_dir config_dir="${CHEZMOI_GH_CONFIG_DIR:-$HOME/.config/gh-personal}" From 0c833ae06835254ac9164803aee6402bdc5e5bd4 Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 10:01:52 -0600 Subject: [PATCH 5/6] fix(delta): highlight chezmoi .tmpl files in jj diff Delta/syntect do not recognize the .tmpl extension, so jj diff/show rendered chezmoi templates as plain text. Default to Bash syntax in chezmoi and dotfiles repos via scoped jj pager and gitconfig-chezmoi; add bat --map-syntax for previews. Per-host languages (toml vs bash) and Go template overlay remain future work until delta supports map-syntax or combined grammars. Verify: chezmoi apply && jj diff dot_bash_profile.tmpl --- dot_config/bat/config | 3 +++ dot_config/jj/config.toml.tmpl | 6 ++++++ dot_gitconfig-chezmoi.tmpl | 4 ++++ dot_gitconfig.tmpl | 8 ++++++++ 4 files changed, 21 insertions(+) create mode 100644 dot_gitconfig-chezmoi.tmpl diff --git a/dot_config/bat/config b/dot_config/bat/config index cd52388..db9bb8c 100644 --- a/dot_config/bat/config +++ b/dot_config/bat/config @@ -1,3 +1,6 @@ # Match Neovim tokyonight-night (see dot_config/bat/themes/tokyonight_night.tmTheme). --theme="tokyonight_night" --style="plain" + +# Chezmoi templates use .tmpl; map to Bash (see ranger executable_scope.sh). +--map-syntax="*.tmpl:Bash" diff --git a/dot_config/jj/config.toml.tmpl b/dot_config/jj/config.toml.tmpl index e49106a..35d3914 100644 --- a/dot_config/jj/config.toml.tmpl +++ b/dot_config/jj/config.toml.tmpl @@ -48,6 +48,12 @@ email = {{ .git.personal.email | quote }} [--scope.signing] key = {{ .git.personal.signingkey | quote }} +# Delta does not recognize .tmpl; default to Bash in chezmoi/dotfiles repos. +[[--scope]] +--when.repositories = [{{ $dotfilesRepoDir | quote }}, {{ $chezmoiSourceDir | quote }}] +[--scope.ui] +pager = ["delta", "--default-language", "bash"] + [[--scope]] --when.repositories = ["~/dev/repos/github.com/{{ $personalGithubUser }}"] [--scope.user] diff --git a/dot_gitconfig-chezmoi.tmpl b/dot_gitconfig-chezmoi.tmpl new file mode 100644 index 0000000..f59ce89 --- /dev/null +++ b/dot_gitconfig-chezmoi.tmpl @@ -0,0 +1,4 @@ +# Chezmoi source uses .tmpl extensions that delta/syntect do not recognize. +# Treat unknown extensions as Bash (matches ranger preview and most tmpl content). +[delta] + default-language = bash diff --git a/dot_gitconfig.tmpl b/dot_gitconfig.tmpl index 7fddb0e..4ed6042 100644 --- a/dot_gitconfig.tmpl +++ b/dot_gitconfig.tmpl @@ -134,3 +134,11 @@ path = ~/.gitconfig-personal [includeIf "gitdir/i:{{ $chezmoiSourceGitDir }}"] path = ~/.gitconfig-personal +[includeIf "gitdir:{{ $chezmoiSourceGitDir }}"] + path = ~/.gitconfig-chezmoi +[includeIf "gitdir/i:{{ $chezmoiSourceGitDir }}"] + path = ~/.gitconfig-chezmoi +[includeIf "gitdir:{{ $dotfilesGitDir }}"] + path = ~/.gitconfig-chezmoi +[includeIf "gitdir/i:{{ $dotfilesGitDir }}"] + path = ~/.gitconfig-chezmoi From f4b3099cb3da5edb9b56c6396b57cc3bbe003454 Mon Sep 17 00:00:00 2001 From: aguil Date: Mon, 8 Jun 2026 10:02:04 -0600 Subject: [PATCH 6/6] fix(shell): init zoxide after mise so cd stays on zoxide profile.d ran zoxide before mise activate, so mise's __zsh_like_cd replaced zoxide's cd. Defer zoxide init until after mise and re-wrap __zoxide_cd in bash so mise hook-env still runs on directory changes. Verify: chezmoi apply && source ~/.bash_profile && type cd --- dot_bash_profile.tmpl | 3 +++ .../chezmoi/profile.d/zoxide-init.sh.tmpl | 26 ++++++++++++++----- dot_zshrc.tmpl | 3 +++ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/dot_bash_profile.tmpl b/dot_bash_profile.tmpl index 8704344..91048ed 100644 --- a/dot_bash_profile.tmpl +++ b/dot_bash_profile.tmpl @@ -123,6 +123,9 @@ if [ -z "$INTELLIJ_ENVIRONMENT_READER" ] && command -v mise >/dev/null 2>&1; the export __MISE_EXE fi fi +if type chez_init_zoxide_cd >/dev/null 2>&1; then + chez_init_zoxide_cd +fi {{- end }} # HACK: to get conda 4.7.5 working again diff --git a/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl index 971850d..931d119 100644 --- a/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl +++ b/dot_config/chezmoi/profile.d/zoxide-init.sh.tmpl @@ -1,14 +1,28 @@ {{- if ne .chezmoi.os "windows" }} -# zoxide: replace cd with smart jumps in human shells. Agent subprocesses keep -# builtin cd and do not write to the zoxide database. +# zoxide: replace cd with smart jumps in human shells. Loaded from profile.d but +# must run after mise activate (see dot_bash_profile / dot_zshrc) so mise does not +# overwrite zoxide's cd with __zsh_like_cd. -if [ -z "${INTELLIJ_ENVIRONMENT_READER:-}" ] && command -v zoxide >/dev/null 2>&1; then +chez_init_zoxide_cd() { + if [ -n "${INTELLIJ_ENVIRONMENT_READER:-}" ] || ! command -v zoxide >/dev/null 2>&1; then + return 0 + fi if type _is_agent_shell >/dev/null 2>&1 && _is_agent_shell; then - : - elif [ -n "${ZSH_VERSION:-}" ]; then + return 0 + fi + + if [ -n "${ZSH_VERSION:-}" ]; then eval "$(zoxide init zsh --cmd cd)" else eval "$(zoxide init bash --cmd cd)" + # Bash: zoxide uses plain `builtin cd` and does not run chpwd_functions, so + # re-wrap __zoxide_cd to keep mise hook-env on directory changes. + if declare -F _mise_hook_chpwd >/dev/null 2>&1 && declare -F __zoxide_cd >/dev/null 2>&1; then + eval "$(declare -f __zoxide_cd | sed '1s/__zoxide_cd/__zoxide_cd_orig/')" + __zoxide_cd() { + __zoxide_cd_orig "$@" && _mise_hook_chpwd + } + fi fi -fi +} {{- end }} diff --git a/dot_zshrc.tmpl b/dot_zshrc.tmpl index 995a058..bedcc99 100644 --- a/dot_zshrc.tmpl +++ b/dot_zshrc.tmpl @@ -30,6 +30,9 @@ if command -v mise >/dev/null 2>&1; then export __MISE_EXE fi fi +if typeset -f chez_init_zoxide_cd >/dev/null 2>&1; then + chez_init_zoxide_cd +fi if [ -z "${INTELLIJ_ENVIRONMENT_READER:-}" ] && [ -f "$HOME/.config/oh-my-posh/shell-init.sh" ]; then # shellcheck source=/dev/null . "$HOME/.config/oh-my-posh/shell-init.sh" zsh