Skip to content

Commit 773e4db

Browse files
committed
Initial commit
0 parents  commit 773e4db

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/vendor

README.md

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# BASH auto complete plugin for Composer
2+
3+
This is an experimental hack to add [Symfony BASH auto complete](https://github.com/stecman/symfony-console-completion) to Composer via a plugin. It's a pretty slimy hack, but it works without editing Composer's code.
4+
5+
![Composer BASH completion](https://i.imgur.com/MoDWkby.gif)
6+
7+
## Installation
8+
9+
1. Run `composer g require stecman/composer-bash-complete-plugin`
10+
2. Put the following in your bash profile:
11+
12+
```bash
13+
# Modified version of what `composer _completion -g -p composer` generates
14+
# Composer will only load plugins when a valid composer.json is in its working directory,
15+
# so for this hack to work, we are always running the completion command in ~/.composer
16+
function _composercomplete {
17+
export COMP_LINE COMP_POINT COMP_WORDBREAKS;
18+
19+
RESULT=`cd $HOME/.composer && composer _completion`;
20+
STATUS=$?;
21+
22+
if [ $STATUS -ne 0 ]; then
23+
echo $RESULT;
24+
return $?;
25+
fi;
26+
27+
local cur;
28+
_get_comp_words_by_ref -n : cur;
29+
30+
COMPREPLY=(`compgen -W "$RESULT" -- $cur`);
31+
32+
__ltrim_colon_completions "$cur";
33+
};
34+
complete -F _composercomplete composer;
35+
```
36+
37+
3. Reload your bash profile (or open a new shell), and enjoy tab completion on Composer
38+
39+
## Explanation
40+
41+
This hacky plugin injects an additional command into the Composer application at runtime. It relies on the fact that when handling an uncaught exception, `Composer\Console\Application::renderException` is called, which in turn calls `getComposer` and causes Composer plugins to be loaded. When the plugin in this package is activated and the first command line argument is `_completion`, the plugin effectively reboots the application with the completion command added.

composer.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "stecman/composer-bash-completion-plugin",
3+
"type": "composer-plugin",
4+
5+
"extra": {
6+
"class": "\\Stecman\\Component\\Symfony\\Console\\BashCompletion\\BashCompletionPlugin"
7+
},
8+
9+
"require": {
10+
"composer-plugin-api": "1.0.0",
11+
"stecman/symfony-console-completion": "~0.3.0"
12+
},
13+
14+
"autoload": {
15+
"psr-4": {
16+
"Stecman\\Component\\Symfony\\Console\\BashCompletion\\": "src"
17+
}
18+
}
19+
}

src/BashCompletionPlugin.php

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Stecman\Component\Symfony\Console\BashCompletion;
4+
5+
use Composer\Composer;
6+
use Composer\IO\IOInterface;
7+
use Composer\Plugin\PluginInterface;
8+
use Stecman\Component\Symfony\Console\BashCompletion\CompletionCommand;
9+
use Symfony\Component\Console\Input\ArgvInput;
10+
11+
class BashCompletionPlugin implements PluginInterface
12+
{
13+
/**
14+
* @var \Symfony\Component\Console\Input\ArgvInput
15+
*/
16+
protected $input;
17+
18+
public function activate(Composer $composer, IOInterface $io)
19+
{
20+
global $application;
21+
global $__bashCompletionInjected;
22+
23+
if ($this->getInput()->getFirstArgument() === '_completion' && !$__bashCompletionInjected) {
24+
$__bashCompletionInjected = true;
25+
26+
$application->add(new CompletionCommand());
27+
$application->run();
28+
die();
29+
}
30+
}
31+
32+
/**
33+
* @return ArgvInput
34+
*/
35+
protected function getInput()
36+
{
37+
if (!$this->input) {
38+
$this->input = new ArgvInput();
39+
}
40+
41+
return $this->input;
42+
}
43+
}

0 commit comments

Comments
 (0)