1
votes

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.

1
This is probably just doomed: what is (destructuring-bind (a b) c ...) going to do?user5920214
or (let (a b c) ...)Rainer Joswig
@tfb well thanks for the input, but I'm focusing on Lisps that reserve () for function calls. Clojure is very well behaved in this sense, Racket a bit less so, but I prefer the noise that this will generate, over the noise of dictionary based function highlighting.Dominykas Mostauskis
Try syn match lispFunc "\(\('\)\@<!(\)\@<=\<.\{-1,}\>?\{0,1}"Wiktor Stribiżew
> I'm focusing on Lisps that reserve () for function calls I.e. not classic MacCarthy Lisp, ANSI Lisp, nor any of it ancestors like MacLisp or InterLisp, nor Scheme, nor Emacs Lisp, EuLisp, ISLisp ...Kaz

1 Answers

2
votes

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.