Skip to content

Commit 93d8d15

Browse files
committed
[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.
1 parent d76f97c commit 93d8d15

3 files changed

Lines changed: 42 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* [#402](https://github.com/clojure-emacs/clojure-mode/issues/402): Font-lock protocol method docstrings with `font-lock-doc-face`.
2121
* [#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.
2222
* [#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)`).
23+
* [#365](https://github.com/clojure-emacs/clojure-mode/issues/365): Font-lock function names in `letfn` bindings with `font-lock-function-name-face`.
2324
* Fix typos in `clojure-mode-extra-font-locking`: `halt-when?` -> `halt-when`, `simple-indent?` -> `simple-ident?`.
2425
* Fix `doc` and `find-doc` misplaced under `clojure.core` instead of `clojure.repl` in extra font-locking.
2526

clojure-mode.el

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,31 @@ any number of matches of `clojure--sym-forbidden-rest-chars'.")
911911
Matches the rule `clojure--keyword-sym-forbidden-1st-chars' followed by
912912
any number of matches of `clojure--sym-forbidden-rest-chars'."))
913913

914+
(defun clojure--search-letfn-name (limit)
915+
"Search for function names in letfn bindings up to LIMIT.
916+
This is a font-lock MATCHER function that finds each binding name
917+
in a `letfn' binding vector. For each `(symbol' match, it checks
918+
whether the paren is a direct child of a letfn binding vector."
919+
(let ((binding-re (concat "(\\(" clojure--sym-regexp "\\)"))
920+
found)
921+
(while (and (not found)
922+
(re-search-forward binding-re limit t))
923+
;; `save-match-data' is critical: the verification below uses
924+
;; `looking-back' which would overwrite the match data from
925+
;; `re-search-forward' that font-lock needs for the highlight.
926+
(save-match-data
927+
(let ((paren-pos (match-beginning 0)))
928+
(save-excursion
929+
(goto-char paren-pos)
930+
(when (ignore-errors (backward-up-list) t)
931+
(when (eq (char-after) ?\[)
932+
(skip-chars-backward " \t\n\r")
933+
(when (looking-back
934+
"(\\(?:clojure\\.core/\\)?letfn"
935+
(- (point) 25))
936+
(setq found t))))))))
937+
found))
938+
914939
(defconst clojure-font-lock-keywords
915940
(eval-when-compile
916941
`(;; Any def form
@@ -993,6 +1018,9 @@ any number of matches of `clojure--sym-forbidden-rest-chars'."))
9931018
;; Possibly name
9941019
"\\(\\sw+\\)?" )
9951020
(2 font-lock-function-name-face nil t))
1021+
;; Function names in letfn bindings
1022+
(clojure--search-letfn-name
1023+
(1 font-lock-function-name-face))
9961024
;; Special forms
9971025
(,(concat
9981026
"("

test/clojure-mode-font-lock-test.el

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1041,7 +1041,19 @@ DESCRIPTION is the description of the spec."
10411041
(9 13 font-lock-variable-name-face))
10421042

10431043
("*some-var?*"
1044-
(1 11 font-lock-variable-name-face))))
1044+
(1 11 font-lock-variable-name-face)))
1045+
1046+
(when-fontifying-it "should handle letfn binding names"
1047+
("(letfn [(twice [x] (* x 2))])"
1048+
(2 6 font-lock-keyword-face)
1049+
(10 14 font-lock-function-name-face))
1050+
1051+
("(letfn [(twice [x] (* x 2)) (six-times [y] (* (twice y) 3))])"
1052+
(10 14 font-lock-function-name-face)
1053+
(30 38 font-lock-function-name-face))
1054+
1055+
("(clojure.core/letfn [(twice [x] (* x 2))])"
1056+
(23 27 font-lock-function-name-face))))
10451057

10461058
(describe "docstring font-locking"
10471059
(it "should font-lock defn docstrings"

0 commit comments

Comments
 (0)