Hack32.Give Your Tab Key a Workout


Hack 32. Give Your Tab Key a Workout

Use bash programmable completion to autocomplete much more than just filenames.

Tab completion in the bash shell isn't new, and I don't know how I'd live without it. Being able to type, for example, ls fo<tab><tab> and get a list of five or six files that start with "fo" can be very handy. Got a long script name you always mistype? Just type the first few letters and hit Tab twice, and bash will try to complete the name for you. This is a wonderful time-saver that I, for one, sorely miss when I log into other Unix machines where the default shell is csh and tab completion is not set up by default (causing control characters to appear on the command line instead of nice, clean, filenames).

In bash v2.04, "programmable" completion was introduced into the shell. This lets you add strange and wonderful bits of goodness to your bash initialization routines (usually found in ~/.bashrc and ~/.bash_profile).

Your bash initialization routines are dependent on how your shell environment is set upbash can use a global /etc/bashrc, a ~/.bash_profile, a ~/.bashrc, a ~/.profile, and I believe a ~/.login file to get its initialization info.


Here's quick example:

 complete -f -X '!*.@(sxw|stw|sxg|sgl|doc|dot|rtf|txt|htm|html|odt|\ ott|odm)' oowriter 

This looks pretty cryptic, but really it's quite simple. complete is a bash built-in keyword that causes the shell to try to complete the text before the cursor on the command line. The -f flag means we'll be looking to complete a filename. The -X flag specifies that what follows is a pattern to use in performing the match. Since the shell is actually parsing the entire line, it's important to always quote your pattern to make sure no shell expansion takes place, causing odd things to happen when you hit your Tab key.

The pattern itself can be broken down and looked at this way:

 !*.@(extension) 

The leading exclamation point, in this context, says that when performing filename completion, we'll be removing things that do not match this pattern. The string *.@(extension) means "anything, followed by a dot, followed by exactly one occurrence of any of the listed extensions" (here, sxw, stw, sxg, and so on). The @ character is a bash extended globbing character that means, "match exactly one occurrence of the pattern." The | characters in our list of extensions are logical "or" separators. If any match, they'll be included in the file listing generated by hitting the Tab key twice.

The last word on the line (in this case, oowriter) specifies the command to which all the stuff on that line applies. In other words, this complete line won't be touched unless the command being run is oowriter.

You can write thousands of these lines if you want, but it would likely take you forever to think of all the things you'd want to complete, get all the regex patterns right, and then debug the whole thing to make sure only the right filenames are returned. Alternatively, you could just download a preconfigured file put together by a fine fellow named Ian MacDonald, creator of the "bash programmable completion" package, available at http://www.caliban.org/bash/index.shtml#completion. The package consists mostly of simple documentation and a file containing a very large collection of bash completion "cheats." A version I recently downloaded contained over 200 shortcuts!

Many of the shortcuts are very simple file completion patterns that are bound to specific applications, which is more useful than you could ever know. Being able to type tar xvzff<tab><tab> and have only those files with a tar.gz extension returned is wonderful, but shortcuts that complete hostnames after the ssh command (from your known_hosts file) or targets in a Makefile after you type make are truly time-savers for admins who are constantly doing remote administration and building software from source.

The great thing is that the only real dependency is the bash shell itself: the rest of what happens is completely up to you! If you have root access on the local machine, you can create a file under /etc/profile.d called bash_complete. sh, and paste in a bit of code to set up bash completion in a sane way. The code comes straight from the bash distribution's README file:

 bash=${BASH_VERSION%.*}; bmajor=${bash%.*}; bminor=${bash#*.} if [ "$PS1" ] && [ $bmajor -eq 2 ] && [ $bminor '>' 04 ] \ && [ -f /etc/bash_completion ]; then # interactive shell  # Source completion code  . /etc/bash_completion fi unset bash bmajor bminor 

This code does a simple check to make sure the version of bash you're running supports programmable completion, then checks to see if you're launching an interactive shell before sourcing the bash programmable completion file.

Putting this code under /etc/profile.d or in your global /etc/bashrc file allows all users on the machine to reap the benefits of bash programmable completion.

If, on the other hand, you want to use this just for yourself or upload it to your shell account at a web host, you can paste the same code from above into your own ~/.bashrc file.

4.5.1. See Also

  • http://www.caliban.org/bash/index.shtml#completion



Linux Server Hacks (Vol. 2)
BSD Sockets Programming from a Multi-Language Perspective (Programming Series)
ISBN: N/A
EAN: 2147483647
Year: 2003
Pages: 162
Authors: M. Tim Jones

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net