Skip to content

Architecture Overview

my-fzf.sh is the entry point. When sourced in .bashrc, it:

  1. Checks it’s running interactively — aborts silently if not
  2. Checks required dependencies — fzf, fd, rg, bat, zoxide. Aborts with error if any are missing
  3. Warns about optional dependencies — nvim. Continues loading if missing
  4. Defines helpers_frroot(), _fscope(), _fext associative array
  5. Sources all lib modules in order — core → scoped → variants → ext → ops → help
  6. Cleans up temp variables — unsets loop variables to avoid polluting the shell

Three helpers power the command generation:

Terminal window
# Get git repo root, or fallback to current directory
_frroot() { git rev-parse --show-toplevel 2>/dev/null || echo .; }
# Map scope letter to directory path
_fscope() { case $1 in c) echo .;; r) _frroot;; g) echo "$HOME";; esac; }
# Map extension suffix to fd glob patterns
declare -A _fext=(
[md]="md" [ts]="ts tsx mts cts" [js]="js jsx mjs cjs"
[json]="json jsonc" [sh]="sh bash zsh" [css]="css scss sass less"
[svelte]="svelte" [astro]="astro" [html]="html htm" [toml]="toml"
)

Commands are generated by nested for loops that eval function definitions. This keeps the codebase compact — instead of writing 334 functions by hand, a few dozen lines of loops produce all of them.

Scopes (c, r, g)
× Actions (f, d, n, b, z, g, gb, gn)
× Variants (base, -h, -ni, -hni)
× Extensions (md, ts, js, json, sh, css, svelte, astro, html, toml)
× Operations (rm, mv, cp, rn)
  • No config file — Extensions and scopes are hardcoded. Fork the repo to customize.
  • No $EDITOR fallback — nvim is hardcoded. Users who prefer another editor fork the repo.
  • No fallback to find/grepfd and rg are required, not optional. This keeps the implementation simple.
  • Eval-based generation — Intentional. It mirrors the original dotfiles source and keeps the two in sync.
  • Variable cleanup — All temp variables (_s, _v, _e, _ef, _x, _ff, _rf, _f, _MYFZF_DIR) are unset after sourcing to avoid polluting the user’s shell.