Skip to content

Commit 3c8e6c8

Browse files
committed
Merge pull request #1036 from gracjan/pr-qq
Implement font-lock for quasi quoted XML, HTML and JavaScript
2 parents 38c4231 + f3eac92 commit 3c8e6c8

File tree

2 files changed

+69
-1
lines changed

2 files changed

+69
-1
lines changed

haskell-compat.el

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ A process is considered alive if its status is `run', `open',
6565
xref-prompt-for-identifier)))
6666
(find-tag ident next-p))))
6767

68+
(unless (fboundp 'font-lock-ensure)
69+
(defalias 'font-lock-ensure 'font-lock-fontify-buffer))
70+
6871
(provide 'haskell-compat)
6972

7073
;;; haskell-compat.el ends here

haskell-font-lock.el

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,27 @@ This is the case if the \".\" is part of a \"forall <tvar> . <type>\"."
9292
(string= " " (string (char-after start)))
9393
(string= " " (string (char-before start))))))))
9494

95+
;;;###autoload
96+
(defcustom haskell-font-lock-quasi-quote-modes
97+
`(("hsx" . xml-mode)
98+
("hamlet" . xml-mode)
99+
("shamlet" . xml-mode)
100+
("xmlQQ" . xml-mode)
101+
("xml" . xml-mode)
102+
("cmd" . shell-mode)
103+
("sh_" . shell-mode)
104+
("jmacro" . javascript-mode)
105+
("jmacroE" . javascript-mode)
106+
("r" . ess-mode)
107+
("rChan" . ess-mode)
108+
("sql" . sql-mode))
109+
"Mapping from quasi quoter token to fontification mode.
110+
111+
If a quasi quote is seen in Haskell code its contents will have
112+
font faces assigned as if respective mode was enabled."
113+
:group 'haskell
114+
:type '(repeat (cons string symbol)))
115+
95116
;;;###autoload
96117
(defface haskell-keyword-face
97118
'((t :inherit font-lock-keyword-face))
@@ -420,10 +441,54 @@ that should be commented under LaTeX-style literate scripts."
420441
("^\\(\\\\\\)end{code}$" 1 "!"))
421442
haskell-basic-syntactic-keywords))
422443

444+
(defun haskell-font-lock-fontify-block (lang-mode start end)
445+
"Fontify a block as LANG-MODE."
446+
(let ((string (buffer-substring-no-properties start end))
447+
(modified (buffer-modified-p))
448+
(org-buffer (current-buffer)) pos next)
449+
(remove-text-properties start end '(face nil))
450+
(with-current-buffer
451+
(get-buffer-create
452+
(concat " haskell-font-lock-fontify-block:" (symbol-name lang-mode)))
453+
(delete-region (point-min) (point-max))
454+
(insert string " ") ;; so there's a final property change
455+
(unless (eq major-mode lang-mode) (funcall lang-mode))
456+
(font-lock-ensure)
457+
(setq pos (point-min))
458+
(while (setq next (next-single-property-change pos 'face))
459+
(put-text-property
460+
(+ start (1- pos)) (1- (+ start next)) 'face
461+
(get-text-property pos 'face) org-buffer)
462+
(setq pos next)))
463+
(add-text-properties
464+
start end
465+
'(font-lock-fontified t fontified t font-lock-multiline t))
466+
(set-buffer-modified-p modified)))
467+
423468
(defun haskell-syntactic-face-function (state)
424469
"`font-lock-syntactic-face-function' for Haskell."
425470
(cond
426-
((nth 3 state) 'font-lock-string-face) ; as normal
471+
((nth 3 state)
472+
(if (equal ?| (nth 3 state))
473+
;; find out what kind of QuasiQuote is this
474+
(let* ((qqname (save-excursion
475+
(goto-char (nth 8 state))
476+
(skip-syntax-backward "w._")
477+
(buffer-substring-no-properties (point) (nth 8 state))))
478+
(lang-mode (cdr (assoc qqname haskell-font-lock-quasi-quote-modes))))
479+
480+
(if (and lang-mode
481+
(fboundp lang-mode))
482+
(save-excursion
483+
;; find the end of the QuasiQuote
484+
(parse-partial-sexp (point) (point-max) nil nil state
485+
'syntax-table)
486+
(haskell-font-lock-fontify-block lang-mode (nth 8 state) (point))
487+
;; must return nil here so that it is not fontified again as string
488+
nil)
489+
;; fontify normally as string because lang-mode is not present
490+
'font-lock-string-face))
491+
'font-lock-string-face))
427492
;; Else comment. If it's from syntax table, use default face.
428493
((or (eq 'syntax-table (nth 7 state))
429494
(and (eq haskell-literate 'bird)

0 commit comments

Comments
 (0)