branch: elpa/clojure-mode
commit 93d8d1529351cfcdf25e2e65dd2b86da829546ef
Author: Bozhidar Batsov <[email protected]>
Commit: Bozhidar Batsov <[email protected]>
[Fix #365] Font-lock function names in letfn bindings
Add a custom font-lock MATCHER function that highlights function
names in letfn binding vectors with font-lock-function-name-face.
---
CHANGELOG.md | 1 +
clojure-mode.el | 28 ++++++++++++++++++++++++++++
test/clojure-mode-font-lock-test.el | 14 +++++++++++++-
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d182b2b4ac..fcf83c31f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -20,6 +20,7 @@
* [#402](https://github.com/clojure-emacs/clojure-mode/issues/402): Font-lock
protocol method docstrings with `font-lock-doc-face`.
* [#649](https://github.com/clojure-emacs/clojure-mode/issues/649): Fix
`clojure-add-arity` severing arglist metadata (`^String`, `^:keyword`,
`^{...}`) when converting single-arity to multi-arity.
* [#600](https://github.com/clojure-emacs/clojure-mode/issues/600): Fix
`clojure--valid-put-clojure-indent-call-p` rejecting valid indent specs with
nested lists (e.g. `letfn`'s `(1 ((:defn)) nil)`).
+* [#365](https://github.com/clojure-emacs/clojure-mode/issues/365): Font-lock
function names in `letfn` bindings with `font-lock-function-name-face`.
* Fix typos in `clojure-mode-extra-font-locking`: `halt-when?` -> `halt-when`,
`simple-indent?` -> `simple-ident?`.
* Fix `doc` and `find-doc` misplaced under `clojure.core` instead of
`clojure.repl` in extra font-locking.
diff --git a/clojure-mode.el b/clojure-mode.el
index 2e9adafc24..b04cb770b0 100644
--- a/clojure-mode.el
+++ b/clojure-mode.el
@@ -911,6 +911,31 @@ any number of matches of
`clojure--sym-forbidden-rest-chars'.")
Matches the rule `clojure--keyword-sym-forbidden-1st-chars' followed by
any number of matches of `clojure--sym-forbidden-rest-chars'."))
+(defun clojure--search-letfn-name (limit)
+ "Search for function names in letfn bindings up to LIMIT.
+This is a font-lock MATCHER function that finds each binding name
+in a `letfn' binding vector. For each `(symbol' match, it checks
+whether the paren is a direct child of a letfn binding vector."
+ (let ((binding-re (concat "(\\(" clojure--sym-regexp "\\)"))
+ found)
+ (while (and (not found)
+ (re-search-forward binding-re limit t))
+ ;; `save-match-data' is critical: the verification below uses
+ ;; `looking-back' which would overwrite the match data from
+ ;; `re-search-forward' that font-lock needs for the highlight.
+ (save-match-data
+ (let ((paren-pos (match-beginning 0)))
+ (save-excursion
+ (goto-char paren-pos)
+ (when (ignore-errors (backward-up-list) t)
+ (when (eq (char-after) ?\[)
+ (skip-chars-backward " \t\n\r")
+ (when (looking-back
+ "(\\(?:clojure\\.core/\\)?letfn"
+ (- (point) 25))
+ (setq found t))))))))
+ found))
+
(defconst clojure-font-lock-keywords
(eval-when-compile
`(;; Any def form
@@ -993,6 +1018,9 @@ any number of matches of
`clojure--sym-forbidden-rest-chars'."))
;; Possibly name
"\\(\\sw+\\)?" )
(2 font-lock-function-name-face nil t))
+ ;; Function names in letfn bindings
+ (clojure--search-letfn-name
+ (1 font-lock-function-name-face))
;; Special forms
(,(concat
"("
diff --git a/test/clojure-mode-font-lock-test.el
b/test/clojure-mode-font-lock-test.el
index 3b4eb1aa29..1f05aa3e0d 100644
--- a/test/clojure-mode-font-lock-test.el
+++ b/test/clojure-mode-font-lock-test.el
@@ -1041,7 +1041,19 @@ DESCRIPTION is the description of the spec."
(9 13 font-lock-variable-name-face))
("*some-var?*"
- (1 11 font-lock-variable-name-face))))
+ (1 11 font-lock-variable-name-face)))
+
+ (when-fontifying-it "should handle letfn binding names"
+ ("(letfn [(twice [x] (* x 2))])"
+ (2 6 font-lock-keyword-face)
+ (10 14 font-lock-function-name-face))
+
+ ("(letfn [(twice [x] (* x 2)) (six-times [y] (* (twice y) 3))])"
+ (10 14 font-lock-function-name-face)
+ (30 38 font-lock-function-name-face))
+
+ ("(clojure.core/letfn [(twice [x] (* x 2))])"
+ (23 27 font-lock-function-name-face))))
(describe "docstring font-locking"
(it "should font-lock defn docstrings"