bash programmable completion
Last week, I was trying to get my directories all set up in a new development environment, and I ended up with a really deep nesting of directories to get to my actual code. After organizing everything in a standard web application source tree way, with java source code in directories based on the package, and packages named with the standard Sun-recommended naming convention, the path to one of my servlets looked something like this:
/home/spugbrap/projects/appName/src/com/baz/\
bar/foo/servlet/MyServlet.java
I created some soft links to get to specific places within the tree, but sometimes traversing the tree is necessary/useful. Most of the directories in the package hierarchy are *basically* empty except for a single subdirectory, so tab completion should come in handy.
So, to get to that servlet directory from my home directory, I was doing something like this ( indicates where I attempted filename completion by hitting the tab key):
15:04:52 Thu Nov 11 [~]
$ cd pro/app/src/
uh oh. already ran into a problem. When I said the directories in the package hierarchy are *basically* empty, I didn’t mention they contain 1 subdirectory to get to the next level in the package hierarchy, as well as a CVS directory since this is all version controlled. So, when I got to the “src” directory, tab completion was not as useful as I had hoped. I needed a way to ignore the CVS directories when performing completion, so I could just do this to get to my final destination:
15:04:52 Thu Nov 11 [~]
$ cd pro/app/src/////se
So, I googled for a while, finding lots of information on how easy this is to do with “zsh”, or on Mac OS X (I think), but was not finding anything about doing it with “bash”, particularly in cygwin (although I figured that part shouldn’t be relevant).
Eventually, I stumbled across a project that allows you to programmatically tell bash exactly how to complete things, even to the point of completing differently based on the command you’re planning to execute, including completing entries from your ~/.ssh/known_hosts file if your command-line starts with “ssh” when you hit tab. This did exactly what I wanted, and much more, so now my directory navigation is much easier. I still use my soft links most of the time, but when I need to actually traverse the tree manually, I can do it in a minimal number of keystrokes.
Here’s a link to this bash completion project on freshmeat:
http://freshmeat.net/projects/bashcompletion/
Enjoy!
-dave


October 7th, 2008 at 1:35 am
Not only that, you can hack bash_completion’s code to omit CVS directories, just like you wanna.
Change:
# Use standard dir completion if no CDPATH or parameter starts with /,
# ./ or ../
if [ -z "${CDPATH:-}" ] || [[ "$cur" == ?(.)?(.)/* ]]; then
_filedir -d
return 0
fi
To:
# Use standard dir completion if no CDPATH or parameter starts with /,
# ./ or ../
if [ -z "${CDPATH:-}" ] || [[ "$cur" == ?(.)?(.)/* ]]; then
_filedir -d
# omit CVS directories
for (( i = 0; i
Courtesy of: http://dotfiles.org/~hanekomu/.bash_completion
October 7th, 2008 at 1:36 am
Hmm, it really didn’t like the code in there. Just go to the bottom of this page: http://dotfiles.org/~hanekomu/.bash_completion
All is explained. No more annoying CVS directories in your tab complete.
October 9th, 2008 at 9:02 pm
Wow. Does that come up often enough to make a difference? I think it’s really cool that the shell has an option to do this, but I have to question if the time spent coming up with a solution ever pays dividend when compared to the lost time having something come up in a tab. Type an extra letter, tab completion will go to where you want. I guess you’re in situations where there are a lot instances of folders with the same name????? Is that what’s happening???