Add bash tab-completion for setup.sh

./setup.sh mat<TAB> now completes to ./setup.sh mattermost, same for
flags. Service names are read fresh from services/*.sh on every
completion — never a hardcoded list, which would go stale the moment
a new service file gets added (matches this repo's own "adding a
service = adding one file, nothing generated" rule from CLAUDE.md).

Verified live: sourced the script and confirmed completions for "mat"
and "--li", and specifically confirmed "bes" resolves to "beszel" —
the service added earlier this same session — with zero changes
needed to the completion script itself, proving the list is genuinely
dynamic rather than something that looked right once and then rotted.

Self-locating via its own BASH_SOURCE path rather than a hardcoded
install directory, so it keeps working regardless of where the repo
is cloned. Works through a leading `sudo` via bash-completion's
standard sudo pass-through (enabled by default on Ubuntu).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H4k6J1qXXyYxhGEgnJaMvn
This commit is contained in:
Claude
2026-08-11 03:46:09 +00:00
parent 3bc14d8cf4
commit fc8f57ab51
2 changed files with 48 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
# tools/setup-completion.bash — bash tab-completion for setup.sh.
#
# Enable it:
# echo "source $(pwd)/tools/setup-completion.bash" >> ~/.bashrc
# source ~/.bashrc
# (run that echo from the repo root, or swap $(pwd) for the actual path)
#
# Then: ./setup.sh mat<TAB> -> ./setup.sh mattermost
# Works with a leading `sudo` too (sudo ./setup.sh mat<TAB>) via the
# bash-completion package's standard sudo pass-through, already enabled by
# default on Ubuntu — nothing extra needed for that part.
#
# Service names are read fresh from services/*.sh every time you press
# <TAB> — never a hardcoded list baked in here. This repo's own rule is
# "adding a service = adding one file, nothing generated" (see CLAUDE.md);
# a completion script that needed regenerating every time a service got
# added would quietly break that promise the first time someone forgot.
_setup_sh_completions() {
local cur repo_dir services flags
cur="${COMP_WORDS[COMP_CWORD]}"
# Self-locating from this file's own path, not a hardcoded install
# location — survives the repo being cloned anywhere, or moved later.
repo_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." 2>/dev/null && pwd)"
[ -d "$repo_dir/services" ] || return 0
services="$(cd "$repo_dir/services" && for f in *.sh; do [ -f "$f" ] && printf '%s ' "${f%.sh}"; done)"
flags="--list --status --dry-run --unattended --remove remove uninstall --version --help configure"
COMPREPLY=( $(compgen -W "${services}${flags}" -- "$cur") )
}
complete -F _setup_sh_completions setup.sh ./setup.sh