summaryrefslogtreecommitdiffstats
path: root/scripts/gen_completion.py
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-06-30 15:09:34 +0200
committerDanilo M. <danix@danix.xyz>2026-06-30 15:09:34 +0200
commit9c15e172eb5b50796eb050cc5704471bce09e024 (patch)
tree01433901ddd2bb8db3f2498a225c49faae26d295 /scripts/gen_completion.py
parent93dbbe18e934d87ebf6ae6c614bb26f0e9e5afa5 (diff)
downloadfirefly-cli-9c15e172eb5b50796eb050cc5704471bce09e024.tar.gz
firefly-cli-9c15e172eb5b50796eb050cc5704471bce09e024.zip
help, completion: descriptive help text and bash completionv0.2.1
Add group/leaf descriptions to argparse help and richer command help strings. Add generated bash completion (completions/firefly.bash) plus its generator (scripts/gen_completion.py), wired into the command checklist in CLAUDE.md and documented in the README. Bump to 0.2.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Diffstat (limited to 'scripts/gen_completion.py')
-rw-r--r--scripts/gen_completion.py115
1 files changed, 115 insertions, 0 deletions
diff --git a/scripts/gen_completion.py b/scripts/gen_completion.py
new file mode 100644
index 0000000..a97f26b
--- /dev/null
+++ b/scripts/gen_completion.py
@@ -0,0 +1,115 @@
+#!/usr/bin/env python3
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz> GPL-2.0-only
+"""Generate completions/firefly.bash from the live command registry.
+
+ python scripts/gen_completion.py > completions/firefly.bash
+
+No drift: groups, leaves, and per-leaf flags are read straight off the
+argparse subparsers the registry builds.
+"""
+import argparse
+from collections import defaultdict
+
+from firefly_cli import registry
+import firefly_cli.commands # noqa: F401 triggers registration
+
+GROUP_ORDER = ["auth", "account", "category", "tag", "tx"]
+
+
+def collect():
+ groups = defaultdict(dict) # group -> {leaf: [--flag, ...]}
+ for c in registry.all_commands():
+ g, _, leaf = c.name.partition(" ")
+ p = argparse.ArgumentParser()
+ if c.args:
+ c.args(p)
+ opts = []
+ for a in p._actions:
+ opts += [s for s in a.option_strings
+ if s.startswith("--") and s != "--help"]
+ groups[g][leaf] = sorted(opts)
+ return groups
+
+
+def render(groups):
+ order = [g for g in GROUP_ORDER if g in groups]
+ order += [g for g in sorted(groups) if g not in GROUP_ORDER]
+
+ leaf_cases, group_cases = [], []
+ for g in order:
+ leaves = " ".join(sorted(groups[g]))
+ group_cases.append(f' {g}) leaves="{leaves}";;')
+ for leaf in sorted(groups[g]):
+ flags = " ".join(groups[g][leaf])
+ if flags:
+ leaf_cases.append(
+ f' "{g} {leaf}")'.ljust(28) + f'leaf_opts="{flags}";;')
+
+ return TEMPLATE.format(
+ groups=" ".join(order),
+ leaf_cases="\n".join(leaf_cases),
+ group_cases="\n".join(group_cases),
+ )
+
+
+TEMPLATE = '''# bash completion for firefly (firefly-cli)
+# Install: source this file, or drop it in /etc/bash_completion.d/ or
+# /usr/share/bash-completion/completions/firefly
+#
+# Generated by scripts/gen_completion.py -- do not edit by hand.
+# Regenerate when commands change (see CLAUDE.md):
+# python scripts/gen_completion.py > completions/firefly.bash
+
+_firefly() {{
+ local cur prev words cword
+ _init_completion 2>/dev/null || {{
+ cur="${{COMP_WORDS[COMP_CWORD]}}"
+ prev="${{COMP_WORDS[COMP_CWORD-1]}}"
+ words=("${{COMP_WORDS[@]}}")
+ cword=$COMP_CWORD
+ }}
+
+ local global_opts="--human --url --token -h --help"
+ local groups="{groups}"
+
+ # Find the group and leaf among the words (skip the program name at 0).
+ local group="" leaf="" i
+ for ((i=1; i < cword; i++)); do
+ local w="${{words[i]}}"
+ case "$w" in
+ -*) ;; # an option, skip
+ --url|--token) ((i++));; # option that takes a value
+ *)
+ if [[ -z $group ]]; then group="$w"
+ elif [[ -z $leaf ]]; then leaf="$w"
+ fi
+ ;;
+ esac
+ done
+
+ # Leaf-specific options.
+ local leaf_opts=""
+ case "$group $leaf" in
+{leaf_cases}
+ esac
+
+ # Leaves per group.
+ local leaves=""
+ case "$group" in
+{group_cases}
+ esac
+
+ if [[ -z $group ]]; then
+ COMPREPLY=($(compgen -W "$groups $global_opts" -- "$cur"))
+ elif [[ -z $leaf ]]; then
+ COMPREPLY=($(compgen -W "$leaves" -- "$cur"))
+ else
+ COMPREPLY=($(compgen -W "$leaf_opts --help" -- "$cur"))
+ fi
+}}
+complete -F _firefly firefly
+'''
+
+
+if __name__ == "__main__":
+ print(render(collect()), end="")