In bash, executables such as mplayer and imagemagick's "convert" have a cool auto-complete functionality on their command line arguments. For instance, if I type
mplayer <tab><tab>
in one of my video folders, then mplayer will list all media files located in that folder, and only the media files.
Similarly, if I type
convert -<tab><tab>
then I will see all the possible options of the convert script, which is great.
My question is how to achieve a similar functionality, using bash, ruby or python scripts?
This is an example of BASH's smart completion. A basic description is here, a guide to writing your own extensions is here and another (Debian-based) guide is here. And here's a fuller featured introduction to the complete
command (the command that facilitates this behaviour).
EDIT: fixed dead links
This functionality in bash is provided by bash-completion and similar functionality is included in zsh. If you want to add support for some program not currently supported by one of these tools, you need to write your own extensions for them.
The link to writing your own extension in the accepted answer has gone dead. Quoting here from http://web.archive.org/web/20090409201619/http://ifacethoughts.net/2009/04/06/extending-bash-auto-completion/
Bash provides you a way of specifying your keywords, and using them to
auto complete command line arguments for your application. I use vim
as a wiki, task managemer and contacts. The vim helptags system lets
me index the content instead of searching through it, and the speed
shows it. One feature I wanted to add to this was to access these tags
from outside vim.
This can be done in a straight forward way:
$ vim -t tagname
This takes me directly to specific content marked using this tag. However, this will be more productive if I can provide
auto-completion for the tags.
I first defined a Bash function for the vim commandline. I added the
following code to my .bashrc file:
function get {
vim -t $1
} Now I can use get tagname command to get to the content.
Bash programmable completion is done by sourcing the
/etc/bash-completion script. The script lets us add our
auto-completion script /etc/bash-completion.d/ directory and executes
it whenever it is called. So I added a script file called get with the
following code in that directory.
_get()
{
local cur
COMPREPLY=()
#Variable to hold the current word
cur="${COMP_WORDS[COMP_CWORD]}"
#Build a list of our keywords for auto-completion using
#the tags file
local tags=$(for t in `cat /home/anadgouda/wiki/tags | \
awk '{print $1}'`; do echo ${t}; done)
#Generate possible matches and store them in the
#array variable COMPREPLY
COMPREPLY=($(compgen -W "${tags}" $cur))
}
#Assign the auto-completion function _get for our command get.
complete -F _get get Once the /etc/bash-completion is sourced, you will get auto-completion for the tags when you use the get command.
Along with my wiki I use it for all the documentation work and at
times the code too. I also use the tags file created from my code. The
indexing system lets me remember the context instead of the filenames
and directories.
You can tweak this system for any of the tools you use. All you need
to do is get a list of the keywords for your command and give it to
the Bash programmable completion system.