From 5883820cde099decd7c2e9ccadf2c9a2ed73a87f Mon Sep 17 00:00:00 2001 From: Roman Rudakov Date: Sat, 5 Apr 2025 09:25:39 +0200 Subject: [PATCH] Properly highlight function name in letfn form --- CHANGELOG.md | 15 +++---- clojure-ts-mode.el | 9 ++++- test/clojure-ts-mode-font-lock-test.el | 54 +++++++++++++++++++++++++- test/samples/test.clj | 8 ++++ 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71cd655..69b63d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,19 +3,20 @@ ## main (unreleased) - [#62](https://github.com/clojure-emacs/clojure-ts-mode/issues/62): Define `list` "thing" to improve navigation in Emacs 31. -- [#64]: Add defcustom `clojure-ts-auto-remap` to control remapping of `clojure-mode` buffers. -- Improve syntax highlighting: +- [#64](https://github.com/clojure-emacs/clojure-ts-mode/pull/64): Add defcustom `clojure-ts-auto-remap` to control remapping of `clojure-mode` buffers. +- [#66](https://github.com/clojure-emacs/clojure-ts-mode/pull/66): Improve syntax highlighting: - Highlight metadata with single keyword with `clojure-ts-keyword-face`. - Only highlight built-ins from `clojure.core` namespace. - Highlight named lambda functions properly. - Fix syntax highlighting for functions and vars with metadata on the previous line. -- Improve semantic indentation rules to be more consistent with cljfmt. -- Introduce `clojure-ts-semantic-indent-rules` customization option. +- [#67](https://github.com/clojure-emacs/clojure-ts-mode/pull/67): Improve semantic indentation rules to be more consistent with cljfmt. +- [#67](https://github.com/clojure-emacs/clojure-ts-mode/pull/67): Introduce `clojure-ts-semantic-indent-rules` customization option. - [#61](https://github.com/clojure-emacs/clojure-ts-mode/issues/61): Fix issue with indentation of collection items with metadata. -- Proper syntax highlighting for expressions with metadata. -- Add basic support for dynamic indentation via `clojure-ts-get-indent-function`. -- Add support for nested indentation rules. +- [#68](https://github.com/clojure-emacs/clojure-ts-mode/pull/68): Proper syntax highlighting for expressions with metadata. +- [#69](https://github.com/clojure-emacs/clojure-ts-mode/pull/69): Add basic support for dynamic indentation via `clojure-ts-get-indent-function`. +- [#70](https://github.com/clojure-emacs/clojure-ts-mode/pull/70): Add support for nested indentation rules. +- [#71](https://github.com/clojure-emacs/clojure-ts-mode/pull/71): Properly highlight function name in `letfn` form. ## 0.2.3 (2025-03-04) diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el index 1cfa6bd..8862265 100644 --- a/clojure-ts-mode.el +++ b/clojure-ts-mode.el @@ -473,7 +473,14 @@ with the markdown_inline grammar." ((sym_lit name: (sym_name) @def) ((:equal "reify" @def))) (list_lit - (sym_lit name: (sym_name) @font-lock-function-name-face))))) + (sym_lit name: (sym_name) @font-lock-function-name-face)))) + ;; letfn + ((list_lit + ((sym_lit name: (sym_name) @symbol) + ((:equal "letfn" @symbol))) + (vec_lit + (list_lit + (sym_lit name: (sym_name) @font-lock-function-name-face)))))) :feature 'variable ;; def, defonce :language 'clojure diff --git a/test/clojure-ts-mode-font-lock-test.el b/test/clojure-ts-mode-font-lock-test.el index b6ea46c..02e0fa4 100644 --- a/test/clojure-ts-mode-font-lock-test.el +++ b/test/clojure-ts-mode-font-lock-test.el @@ -167,4 +167,56 @@ DESCRIPTION is the description of the spec." (when-fontifying-it "special-forms-with-metadata" ("^long (if true 1 2)" (2 5 font-lock-type-face) - (8 9 font-lock-keyword-face)))) + (8 9 font-lock-keyword-face))) + + (when-fontifying-it "should highlight function name in all known forms" + ("(letfn [(add [x y] + (+ x y)) + (hello [user] + (println \"Hello\" user))] + (dotimes [_ (add 6 8)] + (hello \"John Doe\")))" + (2 6 font-lock-keyword-face) + (10 12 font-lock-function-name-face) + (48 52 font-lock-function-name-face)) + + ("(reify + AutoCloseable + (close [this] (.close this)))" + (2 6 font-lock-keyword-face) + (27 31 font-lock-function-name-face)) + + ("(defrecord TestRecord [field] + AutoCloseable + (close [this] + (.close this)))" + (2 10 font-lock-keyword-face) + (12 21 font-lock-type-face) + (50 54 font-lock-function-name-face)) + + ("(definterface MyInterface + (^String name []) + (^double mass []))" + (2 13 font-lock-keyword-face) + (15 25 font-lock-type-face) + (31 36 font-lock-type-face) + (38 41 font-lock-function-name-face) + (51 56 font-lock-type-face) + (58 61 font-lock-function-name-face)) + + ("(deftype ImageSelection [data] + Transferable + (getTransferDataFlavors + [this] + (into-array DataFlavor [DataFlavor/imageFlavor])))" + (2 8 font-lock-keyword-face) + (10 23 font-lock-type-face) + (50 71 font-lock-function-name-face)) + + ("(defprotocol P + (foo [this]) + (bar-me [this] [this y]))" + (2 12 font-lock-keyword-face) + (14 14 font-lock-type-face) + (19 21 font-lock-function-name-face) + (34 39 font-lock-function-name-face)))) diff --git a/test/samples/test.clj b/test/samples/test.clj index a8a1ae9..842ff5a 100644 --- a/test/samples/test.clj +++ b/test/samples/test.clj @@ -27,6 +27,14 @@ (clojure.core/for []) (honey.sql/for {}) +;; the "add" and "hello" should both have a function name face +(letfn [(add [x y] + (+ x y)) + (hello [user] + (println "Hello" user))] + (dotimes [_ (add 6 8)] + (hello "John Doe"))) + ;; the myfn sexp should have a comment face (mysfn 101 foo