Blog's control panel: | Home | Tags | Index | Rss 2.0

Bash Programmable Completion and Vim blogging

Mon, 09 Apr 2007 | Permalink | Tags: , ,

Last night I came up with some stuff to use vim for blogging. It involves some bash scripts and aliases, and you end up with a blog command you can invoke to create a new post. Once there I thought it'd been cool if doing blog<TAB> listed all my current posts and offered tab completation for partially typed names. Bash programmable completation is what I wanted, but it turned out to be less straightforward and well documented than I expected.

Some readings to start

First of all some reading material:
1. man bash , search for "Programmable Completion"
2. Relevant chapters in the bash reference manual
3. Bash completation (useful as example)

I'm assuming that you have bash_completation installed and enabled. If not, get it from the third link.
I'm also far from mastering this thing, especially for the very little documentation available, whatever is presented here works but is very basic and might not be entirely correct (as you'll see I'm using find where probably compgen should be used)

Concepts

Conceptually what you do is creating a function that returns a listing and assign that function to some command, so when you run it and TAB that function will be invoked, producing a list of items.
In my case I have blog posts in a well-known path with extension .blog, so all I want to do when I do blog<TAB> is to return all the files in that dir with extension .blog or all the files whose name starts with whatever I typed after the command.

Code

Stick this in a file under /etc/bash_completion.d/ and you're ready to go (or at the bottom of /etc/bash_completion if your distro doesn't provide a .d mechanism)
have blog &&
_blog()
{
    COMPREPLY=()
    if [ -z "${COMP_WORDS[COMP_CWORD]}" ] ; then
        cur="*.blog"
    else
        cur="${COMP_WORDS[COMP_CWORD]}*"
    fi
    COMPREPLY=( $(find /path/to/your/blog/ -name "$cur" -printf "%f ") )
}

complete -F _blog blog
The have() function is defined in the /etc/bash_completion and simply checks if that function has already been defined. COMPREPLY is where you're supposed to store your file listing to be used by complete command. complete -F _blog blog assigns the function we just wrote to the blog command making the magic happening.
As I mentioned in the warning I suspect that version to be slightly broken as compgen should be used instead of find, but I couldn't get my head around it. Also, complete has got a -X switch you can use to filter out extensions, so I suspect somewhere that should be used too.




SpikeLab.org is a Filippo Spike Morelli copyright 2005-2008
This work is licensed under Creative Commons Att-SA License.