Skip to content

Add shell completion generation (bash, zsh, fish)#127

Merged
mdub merged 15 commits intomasterfrom
mikewilliams/20260303/shell-completion
Mar 3, 2026
Merged

Add shell completion generation (bash, zsh, fish)#127
mdub merged 15 commits intomasterfrom
mikewilliams/20260303/shell-completion

Conversation

@mdub
Copy link
Copy Markdown
Owner

@mdub mdub commented Mar 3, 2026

Summary

Adds shell completion script generation for bash, zsh, and fish. Closes #45.

  • Opt-in via require "clamp/completion", which adds a hidden --shell-completions SHELL option to all commands
  • Programmatic API: MyCommand.generate_completion(:bash, "myapp")
  • Covers option switches (short, long, --[no-] variants), subcommand names/aliases, and --help
  • Excludes hidden options, consistent with help output

New files

  • lib/clamp/completion.rb — entry point, shared utilities, implicit option
  • lib/clamp/completion/bash_generator.rb — bash completion generator
  • lib/clamp/completion/zsh_generator.rb — zsh completion generator
  • lib/clamp/completion/fish_generator.rb — fish completion generator
  • spec/clamp/completion_spec.rb — 54 specs including syntax validation

Test plan

  • bundle exec rspec — 271 examples, 0 failures
  • bundle exec rubocop — 0 offenses
  • Generated scripts pass syntax validation (bash -n, zsh -n, fish --no-execute)
  • 100% line coverage on completion code

🤖 Generated with Claude Code

mdub and others added 15 commits March 3, 2026 22:38
Plan and process docs for incremental TDD development
of shell completion generation (issue #45).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Opt-in via `require "clamp/completion"`, then:

    MyCommand.generate_completion(:fish, "myapp")

Walks the command tree to generate `complete -c` registrations using
fish builtins __fish_use_subcommand and __fish_seen_subcommand_from.

Handles inherited options, aliases, hidden option exclusion, and
subcommand classes reused across the tree.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Demonstrates shell completion generation with subcommands,
inherited options, and --[no-]commit expansion.

  gitdown --completion fish
  gitdown --completion bash

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Provides a ready-made subcommand for generating shell completions:

    subcommand "completion", "Generate shell completions",
      Clamp::Completion::Command

Then users run: myapp completion fish

The root command class and executable name are inferred at runtime
from context and invocation_path.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SHELL parameter now accepts full paths (e.g. /usr/bin/fish)
and defaults to the $SHELL environment variable.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When clamp/completion is loaded, every command gets a hidden
--shell-completions SHELL option. Like --help, it raises an
exception caught by .run, printing the completion script to stdout.

Works on commands without subcommands:

    myapp --shell-completions fish
    myapp --shell-completions /usr/bin/fish

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The implicit --shell-completions option makes the explicit
subcommand class unnecessary.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate bash completion scripts with subcommand-aware completions,
option/flag handling, and valued-option detection. Extracts shared
tree-walking utilities (walk_command_tree, collect_subcommand_names)
into the Completion module for reuse across generators.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Generate zsh completion scripts using _arguments with state-machine
dispatch for subcommands. Per-node functions use -C flag with
->commands/->args states, _describe for subcommand listings, brace
expansion for short/long switch aliases, and mutual exclusion specs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Redesign walk_command_tree so all generators can use it:
- Path is now an array of Subcommand::Definition objects
- Always yields (even for revisited classes), with has_children flag
- Yields 3 args: (command_class, path, has_children)

Rewrite FishGenerator to use the shared walker instead of its own
recursive generate_command/generate_subcommands methods.
Update BashGenerator for the new API.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mdub mdub force-pushed the mikewilliams/20260303/shell-completion branch from cfa69d4 to be2f2d6 Compare March 3, 2026 11:38
@mdub mdub merged commit 6ca8652 into master Mar 3, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature request] Zsh/Bash autocompletion generator

1 participant