Saturday, April 20, 2013

Partial Explosion

Vim has a powerful regex spell, :help /\%[] . While it might look like the emoticon of a lunging crocodile, this little piece of regex lets vimmers match words in either their full form or any partial reduction thereof. That’s a messy explanation. A showing will help:

The pattern:

/r\%[ead]

Will match: r, re, rea, and read

Unicorns, I know!

This actually gets a lot of love in Vim’s syntax highlighting file for its own language, VimL. I wish it didn’t to be honest. I actually deplore the availability of partial keyword forms like fu instead of the full form function. But that’s not why we’re here today, so let’s move on.

Not all regex engines support this awesome atom. In fact… I don’t know of any other that does.

I am in the process of creating a vim.lang file for source-highlighter. As you would expect, it has a regex based DSL for specifying syntax items. One such item is for keywords. Easy!, I thought, I’ll just grab the keywords from Vim’s syntax files and… oh, crap… It’s infested with \%[]

So… Let’s explode them.

With a quick regex, I got the Vim keywords split out onto separate lines, like this:

a
arga[dd]
ar[gs]
bar
bn[ext]
breaka[dd]

And then we can explode out the partial variations with this little regex:

:%s/^\(.\{-}\)\[\(.\{-}\)\]/\=join(map(range(len(submatch(2))+1),  'submatch(1).strpart(submatch(2), 0, v:val)'), ' ')/

Producing:

a
arga argad argadd
ar arg args
bar
bn bne bnex bnext
breaka breakad breakadd

And just in time for dinner, too.