knplabs/knp-console-autocomplete-bundle
A Symfony bundle that adds shell autocompletion for your console commands, completing command names, arguments, and options in bash and zsh. It makes CLI tools faster and friendlier by suggesting valid values as users type, with minimal setup.
This bundle adds shell tab-completion for a Symfony console application. It is a thin, Symfony2-era convenience bundle: it inspects the Console Application and emits (or serves) a completion script for bash/zsh. It is archived and targets Symfony 2.x, so treat it as a reference/legacy tool rather than a new dependency.
Minimal steps:
# 1. Add the bundle (requires a Symfony 2.x project; modern Symfony will reject constraints)
composer require "knplabs/knp-console-autocomplete-bundle:~1.0"
# 2. app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new Knp\Bundle\ConsoleAutocompleteBundle\KnpConsoleAutocompleteBundle(),
);
return $bundles;
}
Where to look first:
Command/ in the bundle — the completion command and how it is named/aliased.Resources/ — the shell template(s) it ships (bash/zsh snippets, if any).list output: php app/console list to confirm the exact command name (commonly registered as knp:console:autocomplete or a hidden completion command).First use case — wire it into your shell once, then forget it:
# Generate the completion script and source it in your current shell
source <(php app/console <completion-command>)
# Persist for new shells (append once to ~/.bashrc or ~/.zshrc)
echo 'source <(php /path/to/project/app/console <completion-command>)' >> ~/.bashrc
After sourcing, php app/console <TAB> completes command names, and command/option names where the generated script supports them.
Per-project vs. global completion. The completion script is generated from a specific application instance, so it reflects that project's commands. For multiple Symfony apps on one machine, generate a separate script per project and source each with an alias, or generate a combined file at build time:
# Generate once, check into your dotfiles or a build artifact
php app/console <completion-command> > .shell/completion.bash
source .shell/completion.bash
Make completion part of onboarding. Add a Makefile/Composer script target so new developers get it in one step:
"scripts": {
"shell:completion": "php app/console <completion-command> > .shell/completion.bash"
}
Design commands to be completable. The quality of completion is only as good as your command definitions. Give every command a clear setName(), and define arguments/options with meaningful names and defaults in configure():
protected function configure()
{
$this
->setName('app:import')
->addArgument('source', InputArgument::REQUIRED, 'Source identifier (e.g. crm, erp)')
->addOption('dry-run', null, InputOption::VALUE_NONE, 'Do not persist changes');
}
Avoid anonymous or dynamically renamed commands (setName() at runtime) — the completion script is generated from the static command list, so runtime names won't appear.
Docker / devcontainers. Source inside the container, not on the host, because the command list must be generated by the container's PHP:
docker compose exec app bash -lc 'source <(php bin/console <completion-command>)'
Or bake it into the image's .bashrc at build time.
Extension points. The bundle's shell template lives in Resources/; if you need custom behavior (extra aliases, per-command argument completion), override the template in your app's app/Resources/KnpConsoleAutocompleteBundle/ or decorate the bundle's command service. This is the main reason to keep it around in a legacy project.
Command::execute() signature, InputInterface/OutputInterface typing, Command::getDefaultName() introduced in 3.4). The bundle will not install against Symfony 3+/4+ without forking. On a modern app, prefer symfony/console's built-in CompletionCommand (bin/console completion bash) or stecman/symfony-console-completion, which do the same job and are maintained.php app/console list (and include hidden commands: php app/console list --raw) to find the actual completion command before writing docs for your team — bundle-internal naming is not stable across forks.source (or restart the shell).source <(php app/console ...) boots the full kernel on every new shell. Generate to a file and source the file; regenerate only when commands change.<(...) process substitution is bash/zsh-only. If your app/console is a symlink or invoked via a wrapper, the generated script may hardcode the wrong path — regenerate from the canonical path.sh -c, and some IDE terminals don't load .bashrc. Don't rely on completion being present in scripts.php app/console <completion-command> | less) and trace with bash -x when a specific command doesn't complete. If the command appears in list but not in the script, the issue is in the generator, not your shell config.app/console is executable if the script invokes it directly rather than via php app/console.How can I help you explore Laravel packages today?