Cool Vim Trickery

Today I was toying with something absolutely not work related and I wanted to share it with somebody to show how awesome the vim text editor can be.

First though, I really would like to thank Bram Moolenaar for contributing such a useful tool to the world. It may not be the easiest thing in the world to learn, but once you’ve got even the most basic functionality figured out, you can do so much more than other editors will allow. That all goes without even saying how cool its interface is. If you realy like vim, you should head on over to his website and buy a tshirt, sticker, or a poster.

What I was dabbling with was vim colors for syntax highlighting. It turns out that the stock install of vim for Arch linux comes with almost 200 color schemes. I really wanted to see them all but didn’t want to have to keep typing ":colors schemename". That is a lot of repeat key presses after all, something we Linux folk really are not fond of when faced with a situation that a computer can handle for us (automation - what a novel idea).

After some searching, I discovered this vim script that will change your color scheme forwards or backwards by pressing F8 or Shift+F8, respectively. Really neat, but not super automated still. Who wants to set this sucker to a timer and watch it switch every 200 milliseconds? I do I do I do!

That vim script provides a few functions that are bound to the afforementioned hotkeys. The function we are immediately concerned with is called NextColor. This will switch the color scheme to the next in the list.

Here’s where vim gets really cool, even though it already is.

It turns out that there is a list in this vim script that is a statically coded array of scheme names, so if you have more themes installed than those listed in the array, you’re out of luck unless you manually add them. Now, at this point we could probably have vim run a shell command and massage the output to make an array for us at runtime, but where’s the fun in that (that’s just a little TOO automated for the purposes of this article)? I want to rock some vim find and replace regex!

Inserting Shell Command Output

So now, the first thing we’re going to do is insert the output of a shell command to our vim file, specificall ls -1. When in command mode, run

:read !ls -1 /usr/share/vim/vim73/colors/

This should insert a metric bitt load (teehee) of lines if you have very many color schemes.

Ranges in Regex

From here, we want to massage the data with a few vim find and replace regexes. Establish the line that your file list ends at. For me, this was line 207, but this very likely won’t be the case for you. Move the cursor to the first line and run the following in command mode

:.,207s/\.vim//

This will do a find and replace on the text range starting where the cursor is currently (the .) and ending at line 207 (the 207). After that it’s just a standard regex substitution. This should chop off the .vim at the end of each filename.

Next, we need to remove the new lines, comma delimit, and encase in single quotes to match the array format. Again, place your cursor at the first line of your list. Remember the line number of the last line in the list?

:.,207s/\(.*\).vim\n/'\1', /

In this cryptic regex, we replace from the current line (the .) to line 207 any line containing .vim with a line break after it (the .vim\n) with the text preceeding the .vim ( captured by <\(.*\)), encasing that value with single quotes and ending with a comma space (the \1,) encase the entire string with a [ ] and you’ll be set. Just erase the old array set your new one to s.mycolors near the top.

Setting the Rotate Timer

Now there’s one piece left: set the timer. In command mode, do the following and hit enter

:while 1 | sleep 1000m | call NextColor(1) | endwhile

That will rotate through every theme you just added to your array every 1000 milliseconds. Just change the 1000m to whatever you want to make it update at different intervals.

Hello worthless but super awesome functionality!

:while 1 | sleep 1000m | call NextColor(0) | endwhile