Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Symfony Console Autocomplete Laravel Package

bamarni/symfony-console-autocomplete

Adds shell autocompletion for Symfony Console commands, so pressing Tab completes command names, arguments, and options in bash, zsh, and fish. Works with any Symfony Console app, including Composer-installed tools like PHPUnit or Composer itself.

Deep Wiki
Context7

Getting Started

Minimal path from zero to working tab-completion:

  1. Audit the need first. Symfony Console 5.4+ ships native _complete/completion machinery. If your framework already exposes it (some Laravel versions do), use that instead. This package is most useful for custom/legacy Symfony Console binaries and tooling that predates native completion.
  2. Install. Project-scoped is cleaner for an application; global is convenient if you want the same hook for many CLI tools:
    composer require --dev bamarni/symfony-console-autocomplete
    # or
    composer global require bamarni/symfony-console-autocomplete
    
  3. Register the completion command on your Symfony\Component\Console\Application instance:
    #!/usr/bin/env php
    <?php
    require __DIR__.'/vendor/autoload.php';
    
    use Symfony\Component\Console\Application;
    use Bamarni\Composer\Autocomplete\Command\CompletionCommand;
    
    $app = new Application('my-cli');
    $app->add(new CompletionCommand());
    $app->run();
    
  4. Generate and source the shell hook (run _completion --help to confirm exact flag names in your installed version):
    # bash — put in ~/.bashrc
    source <(./bin/my-cli _completion --generate-hook --shell-type=bash)
    
    # zsh — put in ~/.zshrc after compinit
    source <(./bin/my-cli _completion --generate-hook --shell-type=zsh)
    
    # fish — put in ~/.config/fish/config.fish
    ./bin/my-cli _completion --generate-hook --shell-type=fish | source
    
  5. Verify: type ./bin/my-cli <TAB> and confirm command names appear; then try an option: ./bin/my-cli my:command --<TAB>.

Where to look first:

  • README usage section for the canonical hook invocation.
  • Bamarni\Composer\Autocomplete\Command\CompletionCommand source — configure() shows supported options (--generate-hook, --shell-type, program name, etc.); execute() shows how input lines are parsed into suggestions.
  • The generated shell function itself — this is the best debugging artifact because it shows exactly which binary/arguments are invoked on Tab.

First useful case: a custom internal CLI (deploy scripts, code generators, data importers) sharing a Symfony Application. One registration gives discoverable command names, option names, and shortcuts across bash/zsh/fish with no per-command boilerplate.

Implementation Patterns

Standalone Symfony Console app (most common). Add the command once in your application bootstrap. Consider registering it conditionally so it is absent from end-user help output but still usable by developers:

if (getenv('APP_ENV') === 'local') {
    $app->add(new CompletionCommand());
}

Laravel / Artisan integration. Register via the Artisan startup hook in a service provider, ideally gated to local:

use Bamarni\Composer\Autocomplete\Command\CompletionCommand;
use Illuminate\Support\Facades\Artisan;

public function boot(): void
{
    if ($this->app->environment('local')) {
        Artisan::starting(function ($artisan) {
            $artisan->add(new CompletionCommand());
        });
    }
}

Crucially, complete against an executable artisan (shebang #!/usr/bin/env php, chmod +x), or an alias, because shell completion fires on the command word. php artisan <TAB> completes for php, not Artisan.

Distribute completion with your tool. For Composer-installable CLIs, ship an installer command (e.g. my-cli completion:install) that writes the generated hook to ~/.bash_completion.d/ or share/zsh/site-functions/. Package managers (Homebrew formulas) can call the same --generate-hook output at build time.

Multiple tools, one setup. With a global install and a stable Composer bin directory on PATH, the same CompletionCommand can be embedded in every in-house Symfony Console binary. Keep the generated function names unique per tool (usually derived from the program name) to avoid shell-level collisions.

Suggesting option values. The command can usually only complete what the Command definition exposes (names, shortcuts, static argument/option descriptions). For dynamic values (branches, tenant IDs, environments), implement Symfony’s Command::complete() on newer versions so the parser delegates to your callback; on older stacks, provide descriptive placeholder text on the option and accept that values are not completed.

Debugging pattern. Bypass the shell entirely and invoke the internal command directly to see raw suggestions:

./bin/my-cli _completion --shell-type=bash --input="./bin/my-cli dep"

This isolates whether a problem is in your command definitions or in the shell hook wiring.

Gotchas and Tips

  • Maintenance and licensing. Last release was 2022 and the license is reported as NOASSERTION — inspect the actual LICENSE file before redistributing, and pin a version. For new projects on Symfony Console 5.4+, prefer the built-in completion command.
  • Program-name mismatch is the #1 failure mode. The hook registers completion for a specific word. If you invoke php bin/console but the hook was generated for bin/console, or if your zsh alias expands differently from the registered name, completion silently does nothing. Regenerate with the correct program name and use the exact invocation style.
  • Boot cost on every Tab. Each completion fires a fresh PHP process that boots your whole application. A Laravel app boots in hundreds of milliseconds; hitting Tab repeatedly is painful. Mitigate with opcache.enable_cli=1, avoid container booting/DB connections in the completion path, or generate static completion scripts where dynamic suggestions aren’t needed.
  • Docker/Sail environments. Completion runs on the host shell. If the tool only exists inside a container, Tab completion cannot work unless you wrap it in a host-side script that docker execs into the container (which is slow) or generate completions on the host.
  • Zsh ordering and init. Source the hook after autoload -U compinit && compinit. If the hook is bash-compatible rather than native zsh, you may also need autoload -U bashcompinit && bashcompinit before sourcing.
  • Global binary path. composer global require installs into a bin dir that isn’t always on PATH (composer global config bin-dir --absolute). Missing that directory makes both the command and the hook unavailable.
  • Hidden command name. _completion is an internal, underscore-prefixed command. It’s generally hidden from list, but don’t document or depend on its output format as a public API — it can change between releases.
  • Quoting and special characters. Arguments with spaces, =, or quotes can confuse the parser behind --input. If a specific command line misbehaves, test it verbatim through the direct --input= debugging call rather than through the shell.
  • Shell variety. Generate one hook per shell; do not reuse a bash hook in zsh. Fish syntax differs entirely, and .bashrc hooks are not loaded in non-interactive shells (CI, some IDEs, remote SSH session wrappers) — completion failures there are usually environmental, not package bugs.
  • Extension points. The command is a normal Symfony Command, so you can subclass it to change the program name, hide it, or add shell-specific post-processing. For richer suggestions, hook into Symfony’s completion input/output abstractions if your Console version supports them; otherwise the package’s parser only knows command/option metadata.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect