Search code examples
regexvimclojurelispsyntax-highlighting

Syntax highlighting rule to highlight the function reference in a Lisp function call


I'm writing a syntax highlighting rules in Vim for Clojure, or another Lisp where (fn ...) occurs mostly for function calls. I'm stuck at highlighting the first word of a function call, i.e. the function reference. Below is a demo of where I'm at:

Wrong lisp syntax highlighting

As you can see, the first word in the function calls (str in (str a b c d)) is highlighted. However, the first element in the literal lists (1 in '(1 2 3)) is also highlighted, which is unintentional. To emphasize, both literal lists have their first elements highlighted, which is wrong.

Below is the syntax rule that does this highlighting:

syn match lispFunc "'\{0}\((\)\@<=\<.\{-1,}\>?\{0,1}"

Here's how I understand this rule:

  • '\{0}: the character ' must match 0 times;
  • \((\)\@<=: the character ( must match, but not be captured;
  • \<.\{-1,}\>: this matches one word (\< and \> represent beginning and end of a word);
  • ?\{0,1}: if there is a ? character at the end of the word, then consider it part of the word: e.g. the highlighted ? in list? in the picture.

I've experimented quite a bit, but I can't seem to make the first two sub-rules work together.


Solution

  • You may use

    syn match lispFunc "\(\('\)\@<!(\)\@<=\<.\{-1,}\>?\{0,1}"
    

    Here, \(\('\)\@<!(\)\@<= is a positive lookbehind that matches a ( only if it is not preceded with '. This condition is set with a \('\)\@<! negative lookbehind inside the positive lookbehind.