From 944652cc389e974f510c7b4371e2fd9a26d28eff Mon Sep 17 00:00:00 2001 From: Roman Rudakov Date: Fri, 30 May 2025 22:01:10 +0200 Subject: [PATCH 1/2] Cleanup some code - Remove 'append' from clojure-ts--align-query and extend it to match :let vector in 'for' and 'doseq' forms. - Remove hack with setting ':override t' for embedded parsers; it was added before I figured out how to not fontify some strings. --- clojure-ts-mode.el | 57 +++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el index 746062f..4b64582 100644 --- a/clojure-ts-mode.el +++ b/clojure-ts-mode.el @@ -1668,25 +1668,33 @@ BOUND bounds the whitespace search." (defvar clojure-ts--align-query (treesit-query-compile 'clojure - (append - `(((map_lit) @map) - ((ns_map_lit) @ns-map) - ((list_lit - ((sym_lit) @sym - (:match ,(clojure-ts-symbol-regexp clojure-ts-align-binding-forms) @sym)) - (vec_lit) @bindings-vec)) - ((list_lit - ((sym_lit) @sym - (:match ,(clojure-ts-symbol-regexp clojure-ts-align-cond-forms) @sym))) - @cond) - ((anon_fn_lit - ((sym_lit) @sym - (:match ,(clojure-ts-symbol-regexp clojure-ts-align-binding-forms) @sym)) - (vec_lit) @bindings-vec)) - ((anon_fn_lit - ((sym_lit) @sym - (:match ,(clojure-ts-symbol-regexp clojure-ts-align-cond-forms) @sym))) - @cond))))) + `(((map_lit) @map) + ((ns_map_lit) @ns-map) + ((list_lit + ((sym_lit) @sym + (:match ,(clojure-ts-symbol-regexp clojure-ts-align-binding-forms) @sym)) + (vec_lit) @bindings-vec)) + ((list_lit + :anchor + ((sym_lit) @sym + (:match ,(rx bol (or "for" "doseq") eol) @sym)) + (vec_lit + ((kwd_lit) @kwd + (:equal ":let" @kwd)) + :anchor + (vec_lit) @bindings-vec))) + ((list_lit + ((sym_lit) @sym + (:match ,(clojure-ts-symbol-regexp clojure-ts-align-cond-forms) @sym))) + @cond) + ((anon_fn_lit + ((sym_lit) @sym + (:match ,(clojure-ts-symbol-regexp clojure-ts-align-binding-forms) @sym)) + (vec_lit) @bindings-vec)) + ((anon_fn_lit + ((sym_lit) @sym + (:match ,(clojure-ts-symbol-regexp clojure-ts-align-cond-forms) @sym))) + @cond)))) (defvar clojure-ts--align-reader-conditionals-query (treesit-query-compile 'clojure @@ -2564,12 +2572,6 @@ function can also be used to upgrade the grammars if they are outdated." (let ((treesit-language-source-alist clojure-ts-grammar-recipes)) (treesit-install-language-grammar grammar))))) -(defsubst clojure-ts--font-lock-setting-update-override (setting) - "Return SETTING with override set to TRUE." - (let ((new-setting (copy-tree setting))) - (setf (nth 3 new-setting) t) - new-setting)) - (defun clojure-ts--harvest-treesit-configs (mode) "Harvest tree-sitter configs from MODE. Return a plist with the following keys and value: @@ -2578,10 +2580,7 @@ Return a plist with the following keys and value: :simple-indent (from `treesit-simple-indent-rules')" (with-temp-buffer (funcall mode) - ;; We need to set :override t for all external queries, otherwise new faces - ;; won't be applied on top of the string face defined for `clojure-ts-mode'. - (list :font-lock (seq-map #'clojure-ts--font-lock-setting-update-override - treesit-font-lock-settings) + (list :font-lock treesit-font-lock-settings :simple-indent treesit-simple-indent-rules))) (defun clojure-ts--add-config-for-mode (mode) From ea7b1cdedd6ac3083e56db14ee543fabd2730111 Mon Sep 17 00:00:00 2001 From: Roman Rudakov Date: Fri, 30 May 2025 22:40:42 +0200 Subject: [PATCH 2/2] [#15] Introduce clojure-ts-extra-def-forms customization --- CHANGELOG.md | 9 ++++---- README.md | 31 ++++++++++++++++++++++++++ clojure-ts-mode.el | 21 +++++++++++++++++ test/clojure-ts-mode-font-lock-test.el | 19 ++++++++++++++++ 4 files changed, 76 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8545599..2045f19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,12 @@ - [#99](https://github.com/clojure-emacs/clojure-ts-mode/pull/99): Fix bug in `clojure-ts-align` when nested form has extra spaces. - [#99](https://github.com/clojure-emacs/clojure-ts-mode/pull/99): Fix bug in `clojure-ts-unwind` when there is only one expression after threading symbol. -- Introduce `clojure-ts-jank-use-cpp-parser` customization which allows +- [#103](https://github.com/clojure-emacs/clojure-ts-mode/issues/103): Introduce `clojure-ts-jank-use-cpp-parser` customization which allows highlighting C++ syntax in Jank `native/raw` forms. -- Introduce `clojure-ts-clojurescript-use-js-parser` customization which allows - highlighting JS syntax in ClojureScript `js*` forms. - +- [#103](https://github.com/clojure-emacs/clojure-ts-mode/issues/103): Introduce `clojure-ts-clojurescript-use-js-parser` customization which + allows highlighting JS syntax in ClojureScript `js*` forms. +- Introduce the `clojure-ts-extra-def-forms` customization option to specify + additional `defn`-like forms that should be fontified. ## 0.4.0 (2025-05-15) diff --git a/README.md b/README.md index f165b7c..d52ba1c 100644 --- a/README.md +++ b/README.md @@ -318,6 +318,37 @@ highlighted like regular Clojure code. > section](https://www.gnu.org/software/emacs/manual/html_node/emacs/Parser_002dbased-Font-Lock.html) > of the Emacs manual for more details. +#### Extending font-lock rules + +In `clojure-ts-mode` it is possible to specify additional defn-like forms that +should be fontified. For example to highlight the following form from Hiccup +library as a function definition: + +```clojure +(defelem file-upload + "Creates a file upload input." + [name] + (input-field "file" name nil)) +``` + +You can add `defelem` to `clojure-ts-extra-def-forms` list like this: + +```emacs-lisp +(add-to-list 'clojure-ts-extra-def-forms "defelem") +``` + +or set this variable using `setopt`: + +```emacs-lisp +(setopt clojure-ts-extra-def-forms '("defelem")) +``` + +This setting will highlight `defelem` symbol, function name and the docstring. + +**NOTE**: Setting `clojure-ts-extra-def-forms` won't change the indentation rule for +these forms. For indentation rules you should use +`clojure-ts-semantic-indent-rules` variable (see [semantic indentation](#customizing-semantic-indentation) section). + ### Highlight markdown syntax in docstrings By default Markdown syntax is highlighted in the docstrings using diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el index 4b64582..c41f7f3 100644 --- a/clojure-ts-mode.el +++ b/clojure-ts-mode.el @@ -260,6 +260,12 @@ values like this: :safe #'booleanp :type 'boolean) +(defcustom clojure-ts-extra-def-forms nil + "List of forms that should be fontified the same way as defn." + :package-version '(clojure-ts-mode . "0.5") + :safe #'listp + :type '(repeat string)) + (defvar clojure-ts-mode-remappings '((clojure-mode . clojure-ts-mode) (clojurescript-mode . clojure-ts-clojurescript-mode) @@ -468,6 +474,15 @@ if a third argument (the value) is provided. :anchor (str_lit (str_content) ,capture-symbol) @font-lock-doc-face) (:match ,clojure-ts-function-docstring-symbols @_def_symbol)) + ((list_lit :anchor [(comment) (meta_lit) (old_meta_lit)] :* + :anchor (sym_lit) @_def_symbol + :anchor [(comment) (meta_lit) (old_meta_lit)] :* + ;; Function_name + :anchor (sym_lit) + :anchor [(comment) (meta_lit) (old_meta_lit)] :* + :anchor (str_lit (str_content) ,capture-symbol) @font-lock-doc-face) + (:match ,(clojure-ts-symbol-regexp clojure-ts-extra-def-forms) + @_def_symbol)) ;; Captures docstrings in defprotcol, definterface ((list_lit :anchor [(comment) (meta_lit) (old_meta_lit)] :* :anchor (sym_lit) @_def_symbol @@ -630,6 +645,12 @@ literals with regex grammar." "defonce") eol)) @font-lock-keyword-face)) + ((list_lit :anchor [(comment) (meta_lit) (old_meta_lit)] :* + :anchor (sym_lit (sym_name) @font-lock-keyword-face) + :anchor [(comment) (meta_lit) (old_meta_lit)] :* + :anchor (sym_lit (sym_name) @font-lock-function-name-face)) + (:match ,(clojure-ts-symbol-regexp clojure-ts-extra-def-forms) + @font-lock-keyword-face)) ((anon_fn_lit marker: "#" @font-lock-property-face)) ;; Methods implementation diff --git a/test/clojure-ts-mode-font-lock-test.el b/test/clojure-ts-mode-font-lock-test.el index 1fa9ed1..4770ccf 100644 --- a/test/clojure-ts-mode-font-lock-test.el +++ b/test/clojure-ts-mode-font-lock-test.el @@ -230,3 +230,22 @@ DESCRIPTION is the description of the spec." (set-parameter [m ^PreparedStatement s i] (.setObject s i (->pgobject m))))" (81 93 font-lock-function-name-face)))) + +;;;; Extra def forms + +(describe "clojure-ts-extra-def-forms" + (it "should respect the value of clojure-ts-extra-def-forms" + (with-clojure-ts-buffer "(defelem file-upload + \"Creates a file upload input.\" + [name] + (input-field \"file\" name nil))" + (setopt clojure-ts-extra-def-forms '("defelem")) + (clojure-ts-mode) + (font-lock-ensure) + (goto-char (point-min)) + (expect (get-text-property 2 'face) + :to-equal 'font-lock-keyword-face) + (expect (get-text-property 10 'face) + :to-equal 'font-lock-function-name-face) + (expect (get-text-property 25 'face) + :to-equal 'font-lock-doc-face))))