[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[nongnu] elpa/clojure-ts-mode 43dbaddc50: Fix some issues with short ano
From: |
ELPA Syncer |
Subject: |
[nongnu] elpa/clojure-ts-mode 43dbaddc50: Fix some issues with short anonymous functions |
Date: |
Mon, 28 Apr 2025 07:01:52 -0400 (EDT) |
branch: elpa/clojure-ts-mode
commit 43dbaddc506a174f97607599e6ab082db79462da
Author: Roman Rudakov <rrudakov@fastmail.com>
Commit: Bozhidar Batsov <bozhidar@batsov.dev>
Fix some issues with short anonymous functions
---
CHANGELOG.md | 4 +++
clojure-ts-mode.el | 58 ++++++++++++++++++++++++++------
test/clojure-ts-mode-font-lock-test.el | 4 +++
test/clojure-ts-mode-indentation-test.el | 17 ++++++++++
test/samples/test.clj | 13 +++++++
5 files changed, 85 insertions(+), 11 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cecf8a2f24..d40be97361 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,10 @@
- [#11](https://github.com/clojure-emacs/clojure-ts-mode/issues/11): Enable
regex syntax highlighting.
- [#16](https://github.com/clojure-emacs/clojure-ts-mode/issues/16): Add
support for automatic aligning forms.
- [#82](https://github.com/clojure-emacs/clojure-ts-mode/issues/82): Introduce
`clojure-ts-outline-variant`.
+- [#86](https://github.com/clojure-emacs/clojure-ts-mode/pull/86): Better
handling of function literals:
+ - Syntax highlighting of built-in keywords.
+ - Consistent indentation with regular forms.
+ - Support for automatic aligning forms.
## 0.3.0 (2025-04-15)
diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el
index 51c7996a99..340e01625a 100644
--- a/clojure-ts-mode.el
+++ b/clojure-ts-mode.el
@@ -514,6 +514,13 @@ literals with regex grammar."
(:equal "clojure.core" @ns))
name: (sym_name) @font-lock-keyword-face))
(:match ,clojure-ts--builtin-symbol-regexp @font-lock-keyword-face))
+ ((anon_fn_lit meta: _ :* :anchor (sym_lit !namespace name: (sym_name)
@font-lock-keyword-face))
+ (:match ,clojure-ts--builtin-symbol-regexp @font-lock-keyword-face))
+ ((anon_fn_lit meta: _ :* :anchor
+ (sym_lit namespace: ((sym_ns) @ns
+ (:equal "clojure.core" @ns))
+ name: (sym_name) @font-lock-keyword-face))
+ (:match ,clojure-ts--builtin-symbol-regexp @font-lock-keyword-face))
((sym_name) @font-lock-builtin-face
(:match ,clojure-ts--builtin-dynamic-var-regexp
@font-lock-builtin-face)))
@@ -726,6 +733,14 @@ literals with regex grammar."
"Return non-nil if NODE is a Clojure list."
(string-equal "list_lit" (treesit-node-type node)))
+(defun clojure-ts--anon-fn-node-p (node)
+ "Return non-nil if NODE is a Clojure function literal."
+ (string-equal "anon_fn_lit" (treesit-node-type node)))
+
+(defun clojure-ts--opening-paren-node-p (node)
+ "Return non-nil if NODE is an opening paren."
+ (string-equal "(" (treesit-node-text node)))
+
(defun clojure-ts--symbol-node-p (node)
"Return non-nil if NODE is a Clojure symbol."
(string-equal "sym_lit" (treesit-node-type node)))
@@ -1249,7 +1264,8 @@ PARENT not should be a list. If first symbol in the
expression has an
indentation rule in `clojure-ts--semantic-indent-rules-defaults' or
`clojure-ts-semantic-indent-rules' check if NODE should be indented
according to the rule. If NODE is nil, use next node after BOL."
- (and (clojure-ts--list-node-p parent)
+ (and (or (clojure-ts--list-node-p parent)
+ (clojure-ts--anon-fn-node-p parent))
(let* ((first-child (clojure-ts--node-child-skip-metadata parent 0)))
(when-let* ((rule (clojure-ts--find-semantic-rule node parent 0)))
(and (not (clojure-ts--match-with-metadata node))
@@ -1265,7 +1281,8 @@ according to the rule. If NODE is nil, use next node
after BOL."
(defun clojure-ts--match-function-call-arg (node parent _bol)
"Match NODE if PARENT is a list expressing a function or macro call."
- (and (clojure-ts--list-node-p parent)
+ (and (or (clojure-ts--list-node-p parent)
+ (clojure-ts--anon-fn-node-p parent))
;; Can the following two clauses be replaced by checking indexes?
;; Does the second child exist, and is it not equal to the current node?
(treesit-node-child parent 1 t)
@@ -1284,7 +1301,8 @@ according to the rule. If NODE is nil, use next node
after BOL."
"Match NODE if it is an argument to a PARENT threading macro."
;; We want threading macros to indent 2 only if the ->> is on it's own line.
;; If not, then align function arg.
- (and (clojure-ts--list-node-p parent)
+ (and (or (clojure-ts--list-node-p parent)
+ (clojure-ts--anon-fn-node-p parent))
(let ((first-child (treesit-node-child parent 0 t)))
(clojure-ts--symbol-matches-p
clojure-ts--threading-macro
@@ -1335,7 +1353,7 @@ according to the rule. If NODE is nil, use next node
after BOL."
(and prev-sibling
(clojure-ts--metadata-node-p prev-sibling))))
-(defun clojure-ts--anchor-parent-skip-metadata (_node parent _bol)
+(defun clojure-ts--anchor-parent-opening-paren (_node parent _bol)
"Return position of PARENT start for NODE.
If PARENT has optional metadata we skip it and return starting position
@@ -1343,11 +1361,9 @@ of the first child's opening paren.
NOTE: This serves as an anchor function to resolve an indentation issue
for forms with type hints."
- (let ((first-child (treesit-node-child parent 0 t)))
- (if (clojure-ts--metadata-node-p first-child)
- ;; We don't need named node here
- (treesit-node-start (treesit-node-child parent 1))
- (treesit-node-start parent))))
+ (thread-first parent
+ (treesit-search-subtree #'clojure-ts--opening-paren-node-p nil
t 1)
+ (treesit-node-start)))
(defun clojure-ts--match-collection-item-with-metadata (node-type)
"Return a matcher for a collection item with metadata by NODE-TYPE.
@@ -1359,6 +1375,18 @@ if NODE has metadata and its parent has type NODE-TYPE."
(treesit-node-type
(clojure-ts--node-with-metadata-parent node)))))
+(defun clojure-ts--anchor-nth-sibling (n &optional named)
+ "Return the start of the Nth child of PARENT.
+
+NAMED non-nil means count only named nodes.
+
+NOTE: This is a replacement for built-in `nth-sibling' anchor preset,
+which doesn't work properly for named nodes (see the bug
+https://debbugs.gnu.org/cgi/bugreport.cgi?bug=78065)"
+ (lambda (_n parent &rest _)
+ (treesit-node-start
+ (treesit-node-child parent n named))))
+
(defun clojure-ts--semantic-indent-rules ()
"Return a list of indentation rules for `treesit-simple-indent-rules'."
`((clojure
@@ -1385,11 +1413,11 @@ if NODE has metadata and its parent has type NODE-TYPE."
((parent-is "read_cond_lit") parent 3)
((parent-is "tagged_or_ctor_lit") parent 0)
;; https://guide.clojure.style/#body-indentation
- (clojure-ts--match-form-body clojure-ts--anchor-parent-skip-metadata 2)
+ (clojure-ts--match-form-body clojure-ts--anchor-parent-opening-paren 2)
;; https://guide.clojure.style/#threading-macros-alignment
(clojure-ts--match-threading-macro-arg prev-sibling 0)
;; https://guide.clojure.style/#vertically-align-fn-args
- (clojure-ts--match-function-call-arg (nth-sibling 2 nil) 0)
+ (clojure-ts--match-function-call-arg ,(clojure-ts--anchor-nth-sibling 1
t) 0)
;; https://guide.clojure.style/#one-space-indent
((parent-is "list_lit") parent 1))))
@@ -1561,6 +1589,14 @@ have changed."
((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))
(when
clojure-ts-align-reader-conditionals
'(((read_cond_lit) @read-cond)
diff --git a/test/clojure-ts-mode-font-lock-test.el
b/test/clojure-ts-mode-font-lock-test.el
index 02e0fa4e57..05eba9e132 100644
--- a/test/clojure-ts-mode-font-lock-test.el
+++ b/test/clojure-ts-mode-font-lock-test.el
@@ -169,6 +169,10 @@ DESCRIPTION is the description of the spec."
(2 5 font-lock-type-face)
(8 9 font-lock-keyword-face)))
+ (when-fontifying-it "function literals"
+ ("#(or one two)"
+ (3 4 font-lock-keyword-face)))
+
(when-fontifying-it "should highlight function name in all known forms"
("(letfn [(add [x y]
(+ x y))
diff --git a/test/clojure-ts-mode-indentation-test.el
b/test/clojure-ts-mode-indentation-test.el
index fe181f9c63..942175a209 100644
--- a/test/clojure-ts-mode-indentation-test.el
+++ b/test/clojure-ts-mode-indentation-test.el
@@ -184,6 +184,12 @@ DESCRIPTION is a string with the description of the spec."
(#'foo 5
6)")
+(when-indenting-it "should support function literals"
+ "
+#(or true
+ false
+ %)")
+
(when-indenting-it "should support block-0 expressions"
"
(do (aligned)
@@ -462,6 +468,17 @@ b |20])"
(let [a b
c d])")
+ (when-aligning-it "should handle function literals"
+ "
+#(let [hello 1
+ foo \"hone\"]
+ (pringln hello))"
+
+ "
+^{:some :metadata} #(let [foo %
+ bar-zzz %]
+ foo)")
+
(when-aligning-it "should handle a blank line"
"
(let [this-is-a-form b
diff --git a/test/samples/test.clj b/test/samples/test.clj
index 842ff5a71f..18ead86cd2 100644
--- a/test/samples/test.clj
+++ b/test/samples/test.clj
@@ -41,6 +41,19 @@
0 0i)
+;; Function literals
+
+^{:some "metadata"} #(let [foo %
+ bar-zzz %]
+ foo)
+
+#(or one
+ two)
+
+#(let [hello 1
+ foo "hone"]
+ (pringln hello))
+
;; examples of valid namespace definitions
(comment
(ns .validns)
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [nongnu] elpa/clojure-ts-mode 43dbaddc50: Fix some issues with short anonymous functions,
ELPA Syncer <=