alle80 / artcompletion
Zsh completion for Laravel Artisan commands driven by a cacheable JSON manifest. Works with `artisan`, `php artisan`, and `art` aliases.
Requires
- php: ^8.1
- illuminate/console: ^10.0 || ^11.0 || ^12.0 || ^13.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0 || ^13.0
- symfony/console: ^6.2 || ^7.0 || ^8.0
README
Zsh completion for Laravel Artisan commands, driven by a cacheable JSON manifest.
An alternative to Symfony Console's php artisan completion zsh: instead of shelling out to PHP on every <TAB>, a small zsh script reads a pre-built JSON manifest with jq — instant results, identical behaviour whether you type artisan, php artisan, or an art alias, and a single installed copy serves every Laravel project on your machine.
Requirements
- PHP 8.1+, Laravel 10, 11, 12 or 13
- zsh
- jq
Installation
composer require alle80/artcompletion
Generate the manifest and install the completion script:
php artisan completion:build php artisan completion:install
completion:install copies the completion script to ~/.zsh/completions/_art-<project> and offers to append the required lines to your ~/.zshrc (it always asks before touching it):
fpath=($HOME/.zsh/completions $fpath) autoload -Uz compinit && compinit compdef _art-<project> php artisan art
Then restart your shell (exec zsh). If the completion does not show up, clear the compinit cache first: rm -f ~/.zcompdump*.
Usage
php artisan mig<TAB> # command names, with descriptions php artisan migrate --<TAB> # options of the chosen command + global options artisan make:mo<TAB> # works with aliases that expand to `php artisan` art db:<TAB> # and with an `art` alias or wrapper
The manifest is a cache: regenerate it whenever the available commands change (new packages, new make:command classes):
php artisan completion:build
Use --path to write it somewhere else than bootstrap/cache/artisan-completion.json:
php artisan completion:build --path=/tmp/artisan-completion.json
Uninstall
php artisan completion:uninstall
Removes the manifest and the installed completion script, then offers to clean up the related ~/.zshrc lines (always asking before writing): the project's compdef binding is removed — or rebound to another project's script if one is still installed — while the fpath/compinit lines are only removed when nothing else uses ~/.zsh/completions. Stale ~/.zcompdump* caches are cleared so the old mapping does not survive, and empty directories are tidied up.
To remove the package itself afterwards:
composer remove alle80/artcompletion
How it works
completion:buildintrospects every registered Artisan command — built-in, application, and package commands (Filament, Livewire, ...) — and writes a JSON manifest with names, descriptions, arguments, and options.- The zsh script resolves the manifest at completion time by walking up from
$PWDto the nearest directory containing anartisanfile, so one copy of the script works for all your projects and each project completes its own commands. - Namespaced commands (
make:model,migrate:fresh) get their colons escaped for zsh's_describe. --option=<TAB>completes the value part as a path; non-option arguments fall back to file completion.
oh-my-zsh and other frameworks that run compinit
compinit registers #compdef services with a "first definition wins" rule. When a framework runs compinit before the block above (oh-my-zsh does), the system _php or a plugin's _artisan keeps the php/artisan services. That is why the installed block ends with an explicit compdef, which always overrides. Stale mappings can also survive inside ~/.zcompdump* caches — delete those files and restart zsh if something looks wrong.