Bash Programmable Completion and Vim blogging
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)
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.