Blog by Daniel Hauck. Sysadmin, Developer, Blogger.

Honestly, in my opinion bash completion is one of the best features in bash.
If you just want the bash completion file and don’t want to read through all of this, click here.

Huge time saver

Whenever I used to work on the command line all day, I am sure I hit TAB 10,000 times a day. If that is enough. Just imagine, you would have to write all that directories yourself.

When I published pysnipp, I wanted it to have bash completion, because that’s what I would expect of a great command line tool. Developing pysnipp itself took me about 2 or 3 evenings. But figuring out how bash completion works took me at least double of the time. So whenever a wild, untamed command line tool appears in front of me, I tried to implement a bash completion for it, so that the hours of sweat and tears paid. Ok, enough of that hero tales here.

Back to Symfony

My first try on the Symfony Framework was about a year ago, so beginning of 2016, with version 2.7 I think. I didn’t go that far with it, because I disliked annotations (I love them now ;)) and didn’t really get the concepts behind Symfony.

But anyway, I had written a bash completion for it.

If you have read my post about goals for 2017, you know that I am now back to PHP and want to make 2017 my year of PHP and Symfony. By the way, if you really want to get up speed with symfony, check out https://knpuniversity.com/, their screencasts are great.

It already worked, but I made a few tweaks to it and broke it down to the simplest way it can get. So if you get the concept of how it works, you can easily adapt it to any command line tool you want.

The Completion File

Here you got it, now deal with it.

Just joking, description of each line below.

So let’s go through the script, line by line:
1 – 4: Function _available_commands(): Most Important Part, here you gather the available command to complete. You could also put “foo bar baz” here, and bash would give you these values for completion.

6 – 16: Function _symfony(): Here all the magic happens. The variable cur is created, which means current and now if you hit tab and you count equals 1, the variable COMPREPLY gets populated with the result from available commands. Everything else, like recognizing how much of the command you have and typed and so on, is handled by bash completion itself.

19: Here we tell obey the actual complete command and telling it, whenever some types bin/console it should call the _symfony function. At least now you should have recognized, that bash completion doesn’t care much that it’s a directory + script you are calling. So just remember, this completions only works when you are in a symfony project directory.
20: Here the colon is removed from the COMP_WORDBREAKS variable. Since symfony uses colon in commands to divide use cases services and so on, we need to remove that. Otherwise bash would start from the beginning anytime you would type a colon and something like doctrine:doctrine:migrations:migrate would be printed.

Install Bash Completion

On Linux

Typically bash completion is already installed on modern distributions. If not, search for ‘bash completion’ with the package manager of your choice.
Now copy the little script above to /etc/bash_completion.d/symfony and your almost done.
Just open a new terminal, or reload bash with . ~/.bashrc and you good to go.

If you are now in a symfony project dir, try typing

bin/console \<TAB\>\<TAB\>

And you should get something like this:


assets:install doctrine:database:create doctrine:query:sql
cache:clear doctrine:database:drop doctrine:schema:create
cache:warmup doctrine:database:import doctrine:schema:drop
config:dump-reference doctrine:ensure-production-settings doctrine:schema:update
debug:config doctrine:fixtures:load doctrine:schema:validate
debug:container doctrine:generate:crud generate:bundle
debug:event-dispatcher doctrine:generate:entities generate:command
debug:router doctrine:generate:entity generate:controller
debug:translation doctrine:generate:form help
debug:twig doctrine:mapping:convert lint:twig
doctrine:cache:clear-collection-region doctrine:mapping:import lint:yaml
doctrine:cache:clear-entity-region doctrine:mapping:info list
doctrine:cache:clear-metadata doctrine:migrations:diff router:match
doctrine:cache:clear-query doctrine:migrations:execute security:check
doctrine:cache:clear-query-region doctrine:migrations:generate security:encode-password
doctrine:cache:clear-result doctrine:migrations:latest server:run
doctrine:cache:contains doctrine:migrations:migrate server:start
doctrine:cache:delete doctrine:migrations:status server:status
doctrine:cache:flush doctrine:migrations:version server:stop
doctrine:cache:stats doctrine:query:dql translation:update

On Mac

Here we have a little bit more to do. If you haven’t already installed homebrew, now is the best time to do it.
Go to http://brew.sh/ and follow the installation instructions and be sure to come back to me 😉

Now that you have brew available on the command line, it’s quite easy. First we need to make sure bash completion gets installed with:

At the end of the installation brew will tell use, to copy these lines to our ~/.bash_profile:

This 3 lines are used to initialise the bash completion, so be sure to add them. Stay cool, we are almost there.

Now get the completion script and copy it to /usr/local/etc/bash_completion.d/symfony.

So far so good. If you now reload your bash, or logout and login back again, the bash completion will be available in any symfony project.

 

If you have the same problem now, that you login lasts a long time in each terminal, try the following:

  1. Open up /usr/local/etc/bash_completion with your favorite text editor and sudo in front.
  2. Go to line 174 which should look like the following: PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&
  3. Comment it out like this: # PATH=$PATH:/sbin:/usr/sbin:/usr/local/sbin type $1 &>/dev/null &&

Conclusion

There are a lot of other possible ways for symfony to get auto completion and I am sure there are ones with more features that give you all the options. But for me, this is the simplest and best working solution, since it works with every symfony project and I don’t have to touch the project itself. It only completes the first argument, but that’s what I needed, so I don’t have to remember all the commands.

If you need a completion for older versions of symfony, which use app/console instead of bin/console just make sure to replace it in the completion script.

Want more? If you are interested in a more complex bash completion, just tell me in the comments.

And don’t forget to subscribe to my newsletter and check out my social networks for updates.


Comments
Harvey Specter
Posted at 7:25 am February 8, 2017
Miguel González
Reply
Author

Hi, nice post.

If somebody is using oh-my-zsh there is a plugin to accomplish this same auto completion and some useful shortcuts:

https://github.com/robbyrussell/oh-my-zsh/blob/master/plugins/symfony2/symfony2.plugin.zsh

Leave a Reply