As implemented on Bash, autocomplete of paths with multiple components over filesystems on NFS or heavily loaded disks is too slow for what I like. I often find my self aborting (with ^C) half-typed commands simply because I happened to trigger autocomplete and it caused the shell to hang, while autocompleting, for more than a second. So I often end up not using autocomplete at all, it just slows me down.
I am trying an alternative approach, that of declaring statically, beforehand, which are the paths I'm likely to type:
import sys;
patterns = [["s", "/home/alejo/src",
[["s", "svnwiki",
[["t", "trunk"]]],
["c", "chicken-eggs",
[["r", "release",
[["c", "current",
[["sw", "stream-wiki"],
["hs", "html-stream"],
["f", "format-modular"]]]]]]],
["i", "i7on"],
["e", "eekfun"]]],
["d", "/home/alejo/doc",
[["w", "wiki",
[["w", "weblogs",
[["a", "azul",
[["d", "xsvnwiki-discuss"]]],
["r", "arhuaco",
[["d", "xsvnwiki-discuss"]]],
["i", "ikks",
[["d", "xsvnwiki-discuss"]]],
["t", "tagae",
[["d", "xsvnwiki-discuss"]]],
["c", "ceronman",
[["d", "xsvnwiki-discuss"]]]
["*", lambda x: x,
[["d", "xsvnwiki-discuss"]]]]]]],
["bw", "bogowiki"]]],
["", "/",
[["v", "var",
[["l", "log",
[["m", "mail.log"],
["a", "apache2",
[["e", "error.log"],
["a", "access.log"]]]]]]]]]]
def searchMatch(p, w, ws):
if len(p) == 2: return [w] + ws
return [w] + search(p[2], ws)
def search (ps, ws):
if ws == []: return ws
for p in ps:
if p[0] == "*" or p[0] == ws[0]:
if type(p[1]) == str:
return searchMatch(p, p[1], ws[1:])
else:
return searchMatch(p, p[1](ws[0]), ws[1:])
return ws
def translateStr(x):
return "/".join(search(patterns, x.split("/")))
def translateFile(f):
for line in f:
print(translateStr(line[:-1]))
translateFile(sys.stdin)
Of course, I'm adding paths to patterns all the time.
Then in my .bashrc, I declare wrappers for commands that I often use in these paths (e stands for “expanded”):
function expandpath { $1 $(echo $2 | python ~/.expand.py); }
function cde { expandpath cd $1; }
function cate { expandpath cat $1; }
function vie { expandpath vi $1; }
function lse { expandpath ls $1; }
# ...
Another option would be to use the complete shell built-in to set this as the autocomplete command for these commands; I haven't experimented with that yet.
What happens is that my brain quickly and painlessly picks the mappings and then things like the following (to see the comments of this post) come quite naturally for me:
$ cate d/w/w/a/d/*workaround*autocomplete
One minor disadvantage when compared with regular autocomplete is that it doesn't give you feedback about the correctness of the paths you type. However, if you want that feedback, you can just use cde gradually and then press up-arrow to continue typing your command. For example:
$ cde d/w/w # RET for feedback, then UP $ cde d/w/w/a/d
Note also that even though I didn't explicitly list the directory for acme's weblog, I can do things like get to its xsvnwiki-discuss sub-directory with:
$ cde d/w/w/acme/d
What do you think? Feel free to use this method (specially, as I said, if you're often typing paths with lots of components over NFS servers); if you do so, please tell me if it works for you.
How can we improve this?
Last update: 2008-08-18 (Rev 14462)


