diff --git a/CHANGELOG.md b/CHANGELOG.md index b1e73d9b..e7357327 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bugs fixed +* [#544](https://github.com/clojure-emacs/clojure-mode/issues/544): Fix docstring detection when string contains backslash. * [#547](https://github.com/clojure-emacs/clojure-mode/issues/547): Fix font-lock regex for character literals for uppercase chars and other symbols. * [#556](https://github.com/clojure-emacs/clojure-mode/issues/556): Fix renaming of ns aliases containing regex characters. * [#555](https://github.com/clojure-emacs/clojure-mode/issues/555): Fix ns detection for ns forms with complex metadata. diff --git a/clojure-mode.el b/clojure-mode.el index a9ec18f0..3d300478 100644 --- a/clojure-mode.el +++ b/clojure-mode.el @@ -974,46 +974,43 @@ which is called with a single parameter, STATE (which is, in turn, returned by `parse-partial-sexp' at the beginning of the highlighted region)." (if (nth 3 state) - ;; This might be a (doc)string or a |...| symbol. - (let ((startpos (nth 8 state))) - (if (eq (char-after startpos) ?|) - ;; This is not a string, but a |...| symbol. - nil - (let* ((listbeg (nth 1 state)) - (firstsym (and listbeg - (save-excursion - (goto-char listbeg) - (and (looking-at "([ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)") - (match-string 1))))) - (docelt (and firstsym - (function-get (intern-soft firstsym) - lisp-doc-string-elt-property)))) - (if (and docelt - ;; It's a string in a form that can have a docstring. - ;; Check whether it's in docstring position. - (save-excursion - (when (functionp docelt) - (goto-char (match-end 1)) - (setq docelt (funcall docelt))) - (goto-char listbeg) - (forward-char 1) - (ignore-errors - (while (and (> docelt 0) (< (point) startpos) - (progn (forward-sexp 1) t)) - ;; ignore metadata and type hints - (unless (looking-at "[ \n\t]*\\(\\^[A-Z:].+\\|\\^?{.+\\)") - (setq docelt (1- docelt))))) - (and (zerop docelt) (<= (point) startpos) - (progn (forward-comment (point-max)) t) - (= (point) (nth 8 state)))) - ;; In a def, at last position is not a docstring - (not (and (string= "def" firstsym) - (save-excursion - (goto-char startpos) - (goto-char (+ startpos (length (sexp-at-point)) 2)) - (looking-at "[ \r\n\t]*\)"))))) - font-lock-doc-face - font-lock-string-face)))) + ;; This is a (doc)string + (let* ((startpos (nth 8 state)) + (listbeg (nth 1 state)) + (firstsym (and listbeg + (save-excursion + (goto-char listbeg) + (and (looking-at "([ \t\n]*\\(\\(\\sw\\|\\s_\\)+\\)") + (match-string 1))))) + (docelt (and firstsym + (function-get (intern-soft firstsym) + lisp-doc-string-elt-property)))) + (if (and docelt + ;; It's a string in a form that can have a docstring. + ;; Check whether it's in docstring position. + (save-excursion + (when (functionp docelt) + (goto-char (match-end 1)) + (setq docelt (funcall docelt))) + (goto-char listbeg) + (forward-char 1) + (ignore-errors + (while (and (> docelt 0) (< (point) startpos) + (progn (forward-sexp 1) t)) + ;; ignore metadata and type hints + (unless (looking-at "[ \n\t]*\\(\\^[A-Z:].+\\|\\^?{.+\\)") + (setq docelt (1- docelt))))) + (and (zerop docelt) (<= (point) startpos) + (progn (forward-comment (point-max)) t) + (= (point) (nth 8 state)))) + ;; In a def, at last position is not a docstring + (not (and (string= "def" firstsym) + (save-excursion + (goto-char startpos) + (goto-char (end-of-thing 'sexp)) + (looking-at "[ \r\n\t]*\)"))))) + font-lock-doc-face + font-lock-string-face)) font-lock-comment-face)) (defun clojure-font-lock-setup () diff --git a/test/clojure-mode-font-lock-test.el b/test/clojure-mode-font-lock-test.el index ecf5ac88..5baa5551 100644 --- a/test/clojure-mode-font-lock-test.el +++ b/test/clojure-mode-font-lock-test.el @@ -806,7 +806,12 @@ DESCRIPTION is the description of the spec." ("(def foo \n \"usage\" \n \"hello\")" (13 19 font-lock-doc-face) - (24 30 font-lock-string-face))) + (24 30 font-lock-string-face)) + + ("(def test-string\n \"this\\n\n is\n my\n string\")" + (20 24 font-lock-string-face) + (25 26 (bold font-lock-string-face)) + (27 46 font-lock-string-face))) (when-fontifying-it "should handle deftype" ("(deftype Foo)"