I’m trying to write syntax defintion for Clojure’s #_ reader macro. It comments one next form. So this:
abc #_def ghi
Would be equivalent to something like
abc /*def*/ ghi
in C-like languages.
What I’m having trouble is: how to tell Sublime to consume only one form? And that form can be anything: numbers, strings, any amount of nested parens etc. E.g.
abc #_(... [...] ...) def #_"ghi" ...d
Problem is, Sublime definitions assume “consume any number of these” and I see no way to say “consume only one of these”. Since there’s no closing tag, I can’t find an easy way to pop context.
One particularly tricky situation is this:
#_[abc][def]
This should skip [abc]
but read [def]
. So I can’t really pop on whitespace.
To make things even more complicated, one can use multiple #_
in a row. That means “ignore N next forms”.
#_#_abc def ghi
Roughly equivalent to
;; /*/*abc*/ def*/ ght
Some tests I’m using:
; reader comment on symbol
#_abc def
; reader comment on brackets
#_[abc] def
; reader comment on nested brackets
#_[a [b c]] def
; touching forms
#_[abc][def]
#_[abc]def
#_abc[def]
; nested form
[#_[abc]]
; double reader comment
#_#_abc def ghi
And my current impl that almost works except for “touching forms” and “double reader comment” cases
%YAML 1.2
---
# http://www.sublimetext.com/docs/syntax.html
name: Exprimental
scope: source.experimental
variables:
ws: '(?:\s|(,))*'
contexts:
main:
- include: form
immediately-pop:
- match: ''
pop: 1
form:
- include: reader-comment
- include: symbol
- include: brackets
symbol:
- match: '[a-z]+'
scope: source.symbol
brackets:
- match: \[
scope: punctuation.section.brackets.begin
push:
- meta_scope: meta.brackets
- match: \]
scope: punctuation.section.brackets.end
pop: true
- include: main
reader-comment:
- match: '#_{{ws}}'
scope: comment.block
push:
- meta_scope: comment.block
- include: form
- include: immediately-pop
Any advice?