Skip to content

Commit 8f8cc95

Browse files
committed
Implement QuasiQuotes [quote| xx |] as string face
1 parent 60f2bb1 commit 8f8cc95

File tree

1 file changed

+34
-0
lines changed

1 file changed

+34
-0
lines changed

haskell-font-lock.el

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,40 @@ that should be commented under LaTeX-style literate scripts."
354354
(or (not (eq ?\\ (char-before)))
355355
(> 0 (skip-syntax-backward ".")))))
356356
"\\")))
357+
358+
;; QuasiQuotes syntax: [quoter| string |], quoter is unqualified
359+
;; name, no spaces, string is arbitrary (including newlines),
360+
;; finishes at the first occurence of |], no escaping is provided.
361+
;;
362+
;; The quoter cannot be "e", "t", "d", or "p", since those overlap
363+
;; with Template Haskell quotations.
364+
;;
365+
;; QuasiQuotes opens only when outside of a string or a comment
366+
;; and closes only when inside a quasiquote.
367+
;;
368+
;; (syntax-ppss) returns list with two imteresting elements:
369+
;; nth 3. non-nil if inside a string. (it is the character that will
370+
;; terminate the string, or t if the string should be terminated
371+
;; by a generic string delimiter.)
372+
;; nth 4. nil if outside a comment, t if inside a non-nestable comment,
373+
;; else an integer (the current comment nesting).
374+
;;
375+
;; Note also that we need to do in in a single pass, hence a regex
376+
;; that covers both the opening and the ending of a quasiquote.
377+
378+
("\\(\\[[[:alnum:]]+\\)?\\(|\\)\\(?:]\\)?"
379+
(2 (save-excursion
380+
(goto-char (match-beginning 0))
381+
(if (eq ?\[ (char-after))
382+
;; opening case
383+
(unless (or (nth 3 (syntax-ppss))
384+
(nth 4 (syntax-ppss))
385+
(member (match-string 1)
386+
'("[e" "[t" "[d" "[p")))
387+
"|")
388+
;; closing case
389+
(when (eq t (nth 3 (syntax-ppss)))
390+
"|")))))
357391
))
358392

359393
(defconst haskell-bird-syntactic-keywords

0 commit comments

Comments
 (0)