Skip to content

Commit 6700c65

Browse files
author
Bozhidar Batsov
committed
[Fix #251] Font-lock properly docstrings in the presence of metadata
1 parent 5386582 commit 6700c65

File tree

2 files changed

+57
-1
lines changed

2 files changed

+57
-1
lines changed

clojure-mode.el

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,45 @@ Called by `imenu--generic-function'."
505505
(1 'font-lock-regexp-grouping-construct prepend))))
506506
"Default expressions to highlight in Clojure mode.")
507507

508+
(defun clojure-font-lock-syntactic-face-function (state)
509+
(if (nth 3 state)
510+
;; This might be a (doc)string or a |...| symbol.
511+
(let ((startpos (nth 8 state)))
512+
(if (eq (char-after startpos) ?|)
513+
;; This is not a string, but a |...| symbol.
514+
nil
515+
(let* ((listbeg (nth 1 state))
516+
(firstsym (and listbeg
517+
(save-excursion
518+
(goto-char listbeg)
519+
(and (looking-at "([ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)")
520+
(match-string 1)))))
521+
(docelt (and firstsym
522+
(function-get (intern-soft firstsym)
523+
lisp-doc-string-elt-property))))
524+
(if (and docelt
525+
;; It's a string in a form that can have a docstring.
526+
;; Check whether it's in docstring position.
527+
(save-excursion
528+
(when (functionp docelt)
529+
(goto-char (match-end 1))
530+
(setq docelt (funcall docelt)))
531+
(goto-char listbeg)
532+
(forward-char 1)
533+
(condition-case nil
534+
(while (and (> docelt 0) (< (point) startpos)
535+
(progn (forward-sexp 1) t))
536+
;; ignore metadata and type hints
537+
(unless (looking-at "[ \n\t]*\\(\\^[A-Z:].+\\|\\^?{.+\\)")
538+
(setq docelt (1- docelt))))
539+
(error nil))
540+
(and (zerop docelt) (<= (point) startpos)
541+
(progn (forward-comment (point-max)) t)
542+
(= (point) (nth 8 state)))))
543+
font-lock-doc-face
544+
font-lock-string-face))))
545+
font-lock-comment-face))
546+
508547
(defun clojure-font-lock-setup ()
509548
"Configures font-lock for editing Clojure code."
510549
(setq-local font-lock-multiline t)
@@ -517,7 +556,7 @@ Called by `imenu--generic-function'."
517556
nil
518557
(font-lock-mark-block-function . mark-defun)
519558
(font-lock-syntactic-face-function
520-
. lisp-font-lock-syntactic-face-function))))
559+
. clojure-font-lock-syntactic-face-function))))
521560

522561
(defun clojure-font-lock-def-at-point (point)
523562
"Range between the top-most def* and the fourth element after POINT.

test.clj

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@
2626
(.append buf "x is: ")
2727
(.append buf (str x))))
2828

29+
;; metadata doesn't break docstrings
30+
(defn max
31+
"Returns the greatest of the nums."
32+
{:added "1.0"
33+
:inline-arities >1?
34+
:inline (nary-inline 'max)}
35+
([x] x)
36+
([x y] (. clojure.lang.Numbers (max x y)))
37+
([x y & more]
38+
(reduce1 max (max x y) more)))
39+
40+
(defn ^String reverse
41+
"Returns s with its characters reversed."
42+
{:added "1.2"}
43+
[^CharSequence s]
44+
(.toString (.reverse (StringBuilder. s))))
45+
2946
;; useful for testing docstring filling
3047
(defn say-hello
3148
"This is a long doc string to test clojure-fill-docstring. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus sed nunc luctus leo ultricies semper. Nullam id tempor mi. Cras adipiscing scelerisque purus, at semper magna tincidunt ut. Sed eget dolor vitae enim feugiat porttitor. Etiam vulputate pulvinar lacinia. Nam vitae nisl sit amet libero pulvinar pretium nec a dui. Ut luctus elit eu nulla posuere nec feugiat ipsum vehicula. Quisque eu pulvinar neque. Fusce fermentum adipiscing mauris, sit amet accumsan ante dignissim ac. Pellentesque molestie mollis condimentum.

0 commit comments

Comments
 (0)