exupero's blog

Vim syntax range plugin

I've been using the fork of tools.reader outlined in the previous post to write this blog. Individual posts are .clj files that are read form by form, evaluated, then rendered to HTML depending on their metadata.

Because I use Vim, one plugin that's been helpful when writing posts is vim-SyntaxRange, which adds support for multiple syntax highlighting schemes in a single file. By default posts are highlighted as Clojure, but when #md #‘ is encountered, code highlighting switches to Markdown until an unescaped backtick is found. A repo-specific .vimrc configures these markers with

call SyntaxRange#Include('#md #`', '\([\\]\)\@<!`',
                         'mkd', 'NonText', '@Spell')

(The unusual-looking regex given in the second argument is Vimscript for a negative lookbehind, which checks that a backtick isn't preceded by a backslash that escapes it.)

A couple more invocations of Include allow syntax highlighting of Clojure forms within interpolated backtick strings:

call SyntaxRange#Include('~{', '}', 'clojure',
                         'NonText', '@NoSpell')
call SyntaxRange#Include('~(', ')', 'clojure',
                         'NonText', '@NoSpell')

Note that these calls only affect syntax highlighting, and not other language plugins that might be active. For example, editing Markdown still inserts closing parentheses and allows moving words as if they were forms, while jumping to sentence boundaries with ( and ) doesn't work.

Also, the terminating marker for ~() interpolated forms matches the first close paren rather than the one that matches the opening paren, so syntax highlighting of nested Clojure forms within Markdown ends prematurely. For example, #md #‘~(+ (- 1 2) 3)‘ doesn't highlight the final 3) as Clojure. That causes problems with auto-indentation, which thinks the form is still open and creates new lines tabbed in however far the the (- 1 2) occurred in the Markdown. The simple fix is to wrap the () form in ~{}, as in #md #‘~{(+ (- 1 2) 3)}‘. Of course, that only works so long as the interpolated Clojure code doesn't contain a closing curly brace, but in practice I haven't found that to be a problem.

In general, however, my experience editing Markdown in a Clojure file has been far better than my experience editing Clojure in a Markdown file.