feat: add interactive fzf tools for chezmoi apply/show with shared utilities

- New chai function for interactive apply with multi-select and diff preview
- Enhanced chshow for browsing managed files with edit/view modes
- Shared fzf-utils.ts with standardized colors and chezmoi file parsing
- Bash version of fzf abbreviation search with Alt+A binding
This commit is contained in:
2025-12-29 18:33:56 -06:00
parent 3342678c9d
commit a1cf700160
6 changed files with 450 additions and 8 deletions
@@ -0,0 +1,55 @@
function chai --description "Interactive chezmoi apply with fzf diff preview"
# Get status data first (before fzf takes over TTY)
# Script outputs to stderr for "no changes" message, stdout for data
set -l data (fzf-chezmoi-apply.ts 2>/dev/null)
set -l script_status $status
# Handle error or no changes case
if test $script_status -ne 0
return 1
end
if test -z "$data"
echo "No changes to apply"
return 0
end
# Run fzf separately so it gets proper TTY access
set -l selected (printf '%s\n' $data | fzf \
--ansi \
--height=50% \
--reverse \
--delimiter='\t' \
--with-nth=4 \
--nth=1 \
--prompt='Apply Changes > ' \
--preview='chezmoi diff {1} 2>/dev/null | head -100' \
--preview-window=right:60%:wrap \
--multi \
--bind='ctrl-a:toggle-all' \
--marker='* ' \
--pointer='>' \
--header='Tab: toggle | Ctrl+A: all | Enter: apply')
if test $status -ne 0 -o -z "$selected"
echo "Cancelled"
return 1
end
# Apply selected files
set -l targets
for line in $selected
set -l target (string split \t $line)[1]
set -a targets $target
end
set -l count (count $targets)
echo "Applying $count file(s)..."
for target in $targets
echo " $target"
chezmoi apply ~/$target
end
echo "Applied $count file(s)"
end
@@ -1,6 +1,41 @@
function chshow --description "Show rendered chezmoi template via fzf"
set -l target (find {{ .chezmoi.sourceDir | quote }} -name "*.tmpl" -type f | fzf)
if test -n "$target"
cat $target | chezmoi execute-template
function chshow --description "Browse chezmoi managed files with fzf preview"
# Get data from script first (before fzf takes over TTY)
set -l data (fzf-chezmoi-show.ts)
if test $status -ne 0 -o -z "$data"
return 1
end
# Run fzf separately so it gets proper TTY access
set -l result (printf '%s\n' $data | fzf \
--ansi \
--height=50% \
--reverse \
--delimiter='\t' \
--with-nth=4 \
--nth=1,2 \
--prompt='Chezmoi Files > ' \
--preview='chezmoi cat {1} 2>/dev/null || echo "Preview unavailable"' \
--preview-window=right:60%:wrap \
--expect='ctrl-e' \
--header='Enter: view | Ctrl+E: edit source')
if test $status -ne 0 -o -z "$result"
return
end
# Parse result: first line is key, second is selected item
set -l lines (string split \n $result)
set -l key $lines[1]
set -l selected $lines[2]
if test -n "$selected"
set -l target (string split \t $selected)[1]
if test "$key" = "ctrl-e"
chezmoi edit ~/$target
else
echo "─── Rendered: $target ───"
chezmoi cat $target 2>/dev/null || echo "Cannot render file (may be binary or encrypted)"
end
end
end