Caio Romão on anything, really

Custom Directory Completion for Bash

written on Sunday, October 10, 2010

UPDATE: Z-Shell users, check out the post detailing the zsh version

I really dislike writing tildes. I mean, since I use an international keyboard layout (In Portuguese we do some heavy usage of tilde and cedilla), I have to type <SHIFT>~<SPACE> in order to get a single ~ character.

For that reason, I've always used quick commands to change to directories nested from my homedir: first I used aliases, then some pushd/popd tickery and finally some proper bash completion usage. Up 'till a few weeks ago, I'd only used a single command, which would complete the folders inside ~/src/ - but this has changed. I felt the need to have quicker access do my downloads folder (~/download/) and even for my homedir, so I hacked together a simple yet useful completion generator function which I though it might be worthwhile to share.

Here it is:

make_dir_complete() {
    local aliasname=$1
    local dirname=$(readlink -f $2)
    local prgname="__s_${aliasname}__"
    FUNC="function $prgname() {
        local cur len wrkdir;
        local IFS=\$'\\n'
        wrkdir=\"$dirname\"
        cur=\${COMP_WORDS[COMP_CWORD]};
        len=\$((\${#wrkdir} + 2));
        COMPREPLY=( \$(compgen -S/ -d \$wrkdir/\$cur| cut -b \$len-) );
    }"
    ALIAS="$aliasname () { cd \"$dirname/\$*\"; }"
    eval $FUNC
    eval $ALIAS
    complete -o nospace -F $prgname $aliasname
}

The usage is simple: make_dir_complete <shortcut_name> <directory>. So, in my case I'd call make_dir_complete jk ~/src and whenever I type jk <TAB><TAB> it will list to me the directories inside ~/src. More advanced completion like wildcard and partial matching (no fuzzy matching, though. Sorry) also work, thanks to bash's awesome complete function.

There are probably better ways to achieve what I just did, so please let me know if you see any room for improvements :)

This entry was tagged bash and magic