[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/tuareg bb420bf 2/6: Fontify ocamldoc comments
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/tuareg bb420bf 2/6: Fontify ocamldoc comments |
Date: |
Thu, 8 Jul 2021 23:57:20 -0400 (EDT) |
branch: elpa/tuareg
commit bb420bf17607334e495c90fb90ae0d618fea7405
Author: Mattias EngdegÄrd <mattiase@acm.org>
Commit: Mattias EngdegÄrd <mattiase@acm.org>
Fontify ocamldoc comments
This makes markup constructs stand out in order to improve legibility
and reduce the risk of mistakes.
---
tuareg.el | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 145 insertions(+), 4 deletions(-)
diff --git a/tuareg.el b/tuareg.el
index 8608a89..d13654d 100644
--- a/tuareg.el
+++ b/tuareg.el
@@ -471,6 +471,16 @@ Valid names are `browse-url', `browse-url-firefox', etc."
(defvar tuareg-font-lock-extension-node-face
'tuareg-font-lock-extension-node-face)
+(defface tuareg-font-lock-doc-markup-face
+ '((t :inherit font-lock-constant-face)) ; FIXME: find something better
+ "Face for mark-up syntax in OCaml doc comments."
+ :group 'tuareg-faces)
+
+(defface tuareg-font-lock-doc-verbatim-face
+ '((t :inherit fixed-pitch)) ; FIXME: find something better
+ "Face for verbatim text in OCaml doc comments (inside {v ... v})."
+ :group 'tuareg-faces)
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Support definitions
@@ -587,7 +597,7 @@ Regexp match data 0 points to the chars."
(if (or (eq (char-syntax (or (char-before mbegin) ?\ )) syntax)
(eq (char-syntax (or (char-after mend) ?\ )) syntax)
(memq (get-text-property mbegin 'face)
- '(tuareg-doc-face
+ '(font-lock-doc-face
font-lock-string-face
font-lock-comment-face
tuareg-font-lock-error-face
@@ -641,8 +651,6 @@ Regexp match data 0 points to the chars."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Font-Lock
-(defvar tuareg-doc-face 'font-lock-doc-face)
-
(defconst tuareg-font-lock-syntactic-keywords
;; Char constants start with ' but ' can also appear in identifiers.
;; Beware not to match things like '*)hel' or '"hel' since the first '
@@ -701,6 +709,137 @@ Regexp match data 0 points to the chars."
'syntax-table (string-to-syntax "|")))))
(c (error "Unexpected char '%c' starting delimited string" c))))))
+;; FIXME: using nil here is a tad unstable -- sometimes we get a full
+;; fontification as code (which is nice!), sometimes not.
+(defconst tuareg-font-lock-doc-code-face nil
+ "Face to use for parts of a doc comment marked up as code (ie, [TEXT]).")
+
+(defun tuareg-fontify-doc-comment (state)
+ (let ((beg (nth 8 state))
+ (end (save-excursion
+ (parse-partial-sexp (point) (point-max) nil nil state
+ 'syntax-table)
+ (point))))
+ (put-text-property beg end 'face 'font-lock-doc-face)
+ (when (and (eq (char-after (- end 2)) ?*)
+ (eq (char-after (- end 1)) ?\)))
+ (setq end (- end 2))) ; stop before closing "*)"
+ (save-excursion
+ (let ((case-fold-search nil))
+ (goto-char beg)
+ (while (< (point) end)
+ ;; Skip over plain text.
+ (re-search-forward (rx point (+ (or (not (in "{}[]@\\<"))
+ (seq "\\" (in "{}[]@")))))
+ end t)
+ (let ((start (point)))
+ (cond
+ ;; [...]
+ ((eq (following-char) ?\[)
+ ;; Fontify opening bracket.
+ (put-text-property start (1+ start) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ (forward-char)
+ ;; Skip balanced set of brackets.
+ (let ((level 1))
+ (while (and (< (point) end)
+ (re-search-forward (rx (? "\\") (in "[]"))
+ end 'noerror)
+ (let ((next (char-after (match-beginning 0))))
+ (cond
+ ((eq next ?\[)
+ (setq level (1+ level))
+ t)
+ ((eq next ?\])
+ (setq level (1- level))
+ (if (> level 0)
+ t
+ (forward-char -1)
+ nil))
+ (t t)))))
+ (put-text-property (1+ start) (point) 'face
+ tuareg-font-lock-doc-code-face)
+ (if (> level 0)
+ ;; Highlight unbalanced opening bracket.
+ (put-text-property start (1+ start) 'face
+ 'tuareg-font-lock-error-face)
+ ;; Fontify closing bracket.
+ (put-text-property (point) (1+ (point)) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ (forward-char 1))))
+
+ ;; Unbalanced "]"
+ ((eq (following-char) ?\])
+ (put-text-property start (1+ start) 'face
+ 'tuareg-font-lock-error-face)
+ (forward-char 1))
+
+ ;; @-tags.
+ ((looking-at (rx "@" (group (+ (in "a-z" "_")))))
+ (put-text-property start (match-end 0) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ (goto-char (match-end 0))
+ ;; Use code face for the first argument of some tags.
+ (when (and (member (match-string 1) '("param" "raise" "before"))
+ (looking-at (rx (+ space)
+ (group (+ (in "a-zA-Z0-9" "_.'-"))))))
+ (put-text-property (match-beginning 1) (match-end 1) 'face
+ tuareg-font-lock-doc-code-face)
+ (goto-char (match-end 0))))
+
+ ;; Cross-reference.
+ ((looking-at (rx "{!"
+ (? (or "tag" "module" "modtype" "class"
+ "classtype" "val" "type"
+ "exception" "attribute" "method"
+ "section" "const" "recfield")
+ ":")
+ (group (* (in "a-zA-Z0-9" "_.'")))))
+ (put-text-property start (match-beginning 1) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ ;; Use code face for the reference.
+ (put-text-property (match-beginning 1) (match-end 1) 'face
+ tuareg-font-lock-doc-code-face)
+ (goto-char (match-end 0)))
+
+ ;; {v ... v}
+ ((looking-at (rx "{v" (in " \t\n")))
+ (put-text-property start (+ 3 start) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ (forward-char 3)
+ (let ((verbatim-end end))
+ (when (re-search-forward (rx (in " \t\n") "v}")
+ end 'noerror)
+ (setq verbatim-end (match-beginning 0))
+ (put-text-property verbatim-end (point) 'face
+ 'tuareg-font-lock-doc-markup-face))
+ (put-text-property (+ 3 start) verbatim-end 'face
+ 'tuareg-font-lock-doc-verbatim-face)))
+
+ ;; Other {} and <> markup.
+ ((looking-at
+ (rx (or (seq "{"
+ (or (or "-" ":" "_" "^"
+ "b" "i" "e" "C" "L" "R" "ul" "ol" "%")
+ ;; Section header with optional label.
+ (seq (+ digit)
+ (? ":" (+ (in "a-zA-Z0-9" "_"))))
+ ""))
+ "}"
+ ;; The HTML tags recognised by ocamldoc.
+ (seq "<" (? "/")
+ (or "b" "i" "code" "ul" "ol" "li"
+ "center" "left" "right"
+ (seq "h" (+ digit)))
+ ">"))))
+ (put-text-property start (match-end 0) 'face
+ 'tuareg-font-lock-doc-markup-face)
+ (goto-char (match-end 0)))
+
+ ;; Anything else, to make forward progress.
+ (t (forward-char 1))))))))
+ nil)
+
(defun tuareg-font-lock-syntactic-face-function (state)
"`font-lock-syntactic-face-function' for Tuareg."
(if (nth 3 state)
@@ -710,7 +849,7 @@ Regexp match data 0 points to the chars."
(eq (char-after (+ start 2)) ?*)
(not (eq (char-after (+ start 3)) ?*)))
;; This is a documentation comment
- tuareg-doc-face
+ (tuareg-fontify-doc-comment state)
font-lock-comment-face))))
;; Initially empty, set in `tuareg--install-font-lock-1'
@@ -1170,6 +1309,8 @@ This based on the fontification and is faster than
calling `syntax-ppss'."
(memq face '(font-lock-comment-face
font-lock-comment-delimiter-face
font-lock-doc-face
+ tuareg-font-lock-doc-markup-face
+ tuareg-font-lock-doc-verbatim-face
font-lock-string-face)))))
(defun tuareg--pattern-pre-form-let ()
- [nongnu] elpa/tuareg updated (2e8482e -> b59c422), ELPA Syncer, 2021/07/08
- [nongnu] elpa/tuareg bb420bf 2/6: Fontify ocamldoc comments,
ELPA Syncer <=
- [nongnu] elpa/tuareg 1bd1b43 3/6: Rewrite doc comment fontifier as one big regexp, ELPA Syncer, 2021/07/08
- [nongnu] elpa/tuareg 382c09c 1/6: Better face for extension nodes on dark background, ELPA Syncer, 2021/07/08
- [nongnu] elpa/tuareg ad456eb 4/6: Generate the doc comment lexer from a macro, ELPA Syncer, 2021/07/08
- [nongnu] elpa/tuareg 1a2aa93 5/6: Better phrase discovery, ELPA Syncer, 2021/07/08
- [nongnu] elpa/tuareg b59c422 6/6: Merge commit 'refs/pull/254/head' of github.com:/ocaml/tuareg into elpa/tuareg, ELPA Syncer, 2021/07/08