/ root / pages / bashcompletion.html
You're using an old link! - Thankfully, you no longer need to specify a nonstandard port (8080) to access my site. You could've used the more standard: http://pbrisbin.com/pages/bashcompletion.html.
Tab completion FTW! I wrote my first custom bash completion today. It was a useful learning experience I'd like to share through an overly commented example script... Enjoy.
Sat, 13 Feb 2010 22:50:57 -0500
Almost all shells have some form of tab completion: ls -l
./Doc<tab> and it completes to ./Documents. Not
only is this a convenience, but it can really help with long or similarly
named arguments to prevent human error.
I hear that zsh has the best terminal completions, but I can't drag myself away from bash (no matter how enticing those suffix aliases sound).
Anyway, extensions to the normal filename completions in bash can be found in
Arch's bash-completion package. It installs functions in
/etc/bash_completion.d/ for various commands to complete. Turns
out, making custom completion functions isn't all that hard.
I added my first custom bash completion for my bookmark script. The goal was,
if I type bookmark -a li<tab> bash will use the folder
structure under ~/.my_bookmarks to complete the category
argument. That function can be found here for
reference.
I'm planning on doing more of these, because (once I found a good template)
it was extremely easy to create, and immediately stopped me from having to
bookmark -ls to get a list of valid categories before doing
bookmark -a foo/bar url to add it without an error.
Here's a commented example to try and explain how it all works; maybe it can be useful to others
Our script is a killer burning application which accepts .isos for input and
burns them to CD or DVD. It burns with cdrecord when passed -c
something.iso and growisofs when passed -d
something.iso.
We want tab to only complete ISO files in the current directory. But, we're
wicked organized so we actually have a shweet naming convention where-by the
filenames start with cd_ or dvd_ so we know what
will fit on what.
# # /etc/bash_completion.d/killerburn # _killerburn_completion() { # # it's best to declare all variables locally # so that you don't pollute your environment # # you can give them values here or just list # them on one line (or mixed) # local cd_comps dvd_comps cur prev word # the contents of this array are the values # that bash will use as possible completions # # it can be an explicit list of values or the # output of a command # the list we want to complete on -c cd_comps=( $(find ./ -name 'cd_*.iso') ) # and a more different list for -d dvd_comps=( $(find ./ -name 'dvd_*.iso') ) # declare the array that will hold your # responses to tab-completion attempts COMPREPLY=() # get the current word (characters so far) cur=${COMP_WORDS[COMP_CWORD]} # and the most recent word (preceding flag) prev=${COMP_WORDS[COMP_CWORD-1]} # you could even go back further if needed # since we know $prev we can do some useful # logic, you could even use $cur if needed # the comps for -c if [ "$prev" == '-c' ]; then COMPREPLY=( $(compgen -W "\ $( for word in ${cd_comps[@]}; do # these are probably the only echo "$word" # spots you'll ever edit done )" -- $cur ) ) # and the comps for -d elif [ "$prev" == '-d' ]; then COMPREPLY=( $(compgen -W "\ $( for word in ${dvd_comps[@]}; do echo "$word" done )" -- $cur ) ) fi } # now just enable it complete -F _killerburn_complete killerburn
Re-source and try it
pbrisbin dot com 2010
on Mon, 26 Jul 2010 00:55:36 -0400, supulton wrote: