emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/clojure-ts-mode ec48877dd0 4/5: Fix ns docstring highlight


From: ELPA Syncer
Subject: [nongnu] elpa/clojure-ts-mode ec48877dd0 4/5: Fix ns docstring highlighting regression
Date: Fri, 15 Sep 2023 00:59:17 -0400 (EDT)

branch: elpa/clojure-ts-mode
commit ec48877dd0394d176dd08334ee48d1ff48643453
Author: Danny Freeman <danny@dfreeman.email>
Commit: Danny Freeman <danny@dfreeman.email>

    Fix ns docstring highlighting regression
    
    This also begins the process of making our symbol matching regular
    expressions user extensible (see issue #15). There are more to convert
    from regexps to normal lists, but I want to take my time and make sure I
    get the names down correctly. It is important to get maximum reuse so
    users don't have to add their fancy def-whatever to 4 different lists.
---
 clojure-ts-mode.el  | 72 +++++++++++++++++++++++++++++++++--------------------
 test/docstrings.clj | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 112 insertions(+), 27 deletions(-)

diff --git a/clojure-ts-mode.el b/clojure-ts-mode.el
index 224f3b95b1..299fa42bdf 100644
--- a/clojure-ts-mode.el
+++ b/clojure-ts-mode.el
@@ -202,17 +202,26 @@ Only intended for use at development time.")
   '((t (:inherit font-lock-string-face)))
   "Face used to font-lock Clojure character literals.")
 
-(defconst clojure-ts--definition-symbol-regexp
-  (rx
-   line-start
-   (or (group "fn")
-       (group "def"
-              (+ (or alnum
-                     ;; What are valid characters for symbols?
-                     ;; is a negative match better?
-                     "-" "_" "!" "@" "#" "$" "%" "^" "&"
-                     "*" "|" "?" "<" ">" "+" "=" ":"))))
-   line-end))
+(defun clojure-ts-symbol-regexp (symbols)
+  "Return a regular expression that matches one of SYMBOLS exactly."
+  (concat "^" (regexp-opt symbols) "$"))
+
+(defvar clojure-ts-function-docstring-symbols
+  '("definline"
+    "defmulti"
+    "defmacro"
+    "defn"
+    "defn-"
+    "defprotocol"
+    "ns")
+  "Symbols that accept an optional docstring as their second argument.")
+
+(defvar clojure-ts-definition-docstring-symbols
+  '("def")
+  "Symbols that accept an optional docstring as their second argument.
+Any symbols added here should only treat their second argument as a docstring
+if a third argument (the value) is provided.
+\"def\" is the only builtin Clojure symbol that behaves like this.")
 
 (defconst clojure-ts--variable-definition-symbol-regexp
   (eval-and-compile
@@ -244,40 +253,49 @@ Only intended for use at development time.")
 
 (defun clojure-ts--docstring-query (capture-symbol)
   "Return a query that captures docstrings with CAPTURE-SYMBOL."
-  `(;; Captures docstrings in def, defonce
-    ((list_lit :anchor (sym_lit) @def_symbol
+  `(;; Captures docstrings in def
+    ((list_lit :anchor (sym_lit) @_def_symbol
+               :anchor (comment) :?
                :anchor (sym_lit) ; variable name
+               :anchor (comment) :?
                :anchor (str_lit) ,capture-symbol
                :anchor (_)) ; the variable's value
-     (:match ,clojure-ts--variable-definition-symbol-regexp @def_symbol))
+     (:match ,(clojure-ts-symbol-regexp 
clojure-ts-definition-docstring-symbols)
+             @_def_symbol))
     ;; Captures docstrings in metadata of definitions
-    ((list_lit :anchor (sym_lit) @def_symbol
+    ((list_lit :anchor (sym_lit) @_def_symbol
+               :anchor (comment) :?
                :anchor (sym_lit
                         (meta_lit
                          value: (map_lit
-                                 (kwd_lit) @doc-keyword
+                                 (kwd_lit) @_doc-keyword
                                  :anchor
                                  (str_lit) ,capture-symbol))))
      ;; We're only supporting this on a fixed set of defining symbols
      ;; Existing regexes don't encompass def and defn
      ;; Naming another regex is very cumbersome.
-     (:match ,(regexp-opt '("def" "defonce" "defn" "defn-" "defmacro" "ns"
-                            "defmulti" "definterface" "defprotocol"
-                            "deftype" "defrecord" "defstruct"))
-             @def_symbol)
-     (:equal @doc-keyword ":doc"))
+     (:match ,(clojure-ts-symbol-regexp
+               '("def" "defonce" "defn" "defn-" "defmacro" "ns"
+                 "defmulti" "definterface" "defprotocol"
+                 "deftest" "deftest-"
+                 "deftype" "defrecord" "defstruct"))
+             @_def_symbol)
+     (:equal @_doc-keyword ":doc"))
     ;; Captures docstrings defn, defmacro, ns, and things like that
-    ((list_lit :anchor (sym_lit) @def_symbol
+    ((list_lit :anchor (sym_lit) @_def_symbol
+               :anchor (comment) :?
                :anchor (sym_lit) ; function_name
+               :anchor (comment) :?
                :anchor (str_lit) ,capture-symbol)
-     (:match ,clojure-ts--definition-symbol-regexp @def_symbol))
+     (:match ,(clojure-ts-symbol-regexp clojure-ts-function-docstring-symbols)
+             @_def_symbol))
     ;; Captures docstrings in defprotcol, definterface
-    ((list_lit :anchor (sym_lit) @def_symbol
+    ((list_lit :anchor (sym_lit) @_def_symbol
                (list_lit
                 :anchor (sym_lit) (vec_lit) :*
                 (str_lit) ,capture-symbol :anchor)
                :*)
-     (:match ,clojure-ts--interface-def-symbol-regexp @def_symbol))))
+     (:match ,clojure-ts--interface-def-symbol-regexp @_def_symbol))))
 
 (defvar clojure-ts--treesit-range-settings
   (treesit-range-rules
@@ -752,7 +770,7 @@ forms like deftype, defrecord, reify, proxy, etc."
     (and (treesit-node-eq node (treesit-node-child parent 2 t))
          (let ((first-auncle (treesit-node-child parent 0 t)))
            (clojure-ts--symbol-matches-p
-            clojure-ts--definition-symbol-regexp
+            (regexp-opt clojure-ts-function-docstring-symbols)
             first-auncle)))))
 
 (defun clojure-ts--match-def-docstring (node)
@@ -765,7 +783,7 @@ forms like deftype, defrecord, reify, proxy, etc."
          (treesit-node-child parent 3 t)
          (let ((first-auncle (treesit-node-child parent 0 t)))
            (clojure-ts--symbol-matches-p
-            clojure-ts--variable-definition-symbol-regexp
+            (regexp-opt clojure-ts-definition-docstring-symbols)
             first-auncle)))))
 
 (defun clojure-ts--match-method-docstring (node)
diff --git a/test/docstrings.clj b/test/docstrings.clj
new file mode 100644
index 0000000000..c3bb2a773b
--- /dev/null
+++ b/test/docstrings.clj
@@ -0,0 +1,67 @@
+(ns clojure-ts-mode.docstrings
+  "This is a namespace
+  See my famous `fix-bug` macro if you need help."
+  (:require [clojure.test :refer [deftest]])
+  (:import (java.util UUID)))
+
+(def foo ;;asdf
+  "I'm a value")
+(def bar "I'm a docstring" "and I'm a value")
+
+(defonce ^{:doc "gotta document in metadata."} baz
+  "Did you know defonce doesn't have a docstring arity like def?")
+
+(def foobar
+  ;; Comments shouldn't disrupt docstring highlighting
+  "I'm a docstring"
+  123)
+
+(defn ;;asdf
+  foobarbaz ;;asdf
+  "I'm the docstring!" ;;asdf
+  [x]
+  (inc x))
+
+(;; starting comments break docstrings
+ defn busted!
+ "We really need to anchor symbols like defn to the front of the list.
+I don't want every query to have to check for comments.
+Don't format code this way."
+ []
+ nil)
+
+(defn buzz "Looking for `fizz`"
+  [x]
+  (when (zero? (% x 5))
+    "buzz"))
+
+(defn- fizz
+  "Pairs well with `buzz`"
+  [x]
+  (when (zero? (% x 3))
+    "fizz"))
+
+(defmacro fix-bug
+  "Fixes most known bugs."
+  [& body]
+  `(try
+     ~@body
+     (catch Throwable _
+       nil)))
+
+(definline never-used-this ":)" [x] x)
+
+(deftype ^{:doc "asdf" :something-else "asdf"} T
+  java.lang.Closeable
+  (close [this]
+    (print "done")))
+
+(defprotocol Fooable
+  (foo [this]
+    "Does foo"))
+
+(definterface Barable
+  (^String bar [] "Does bar"))
+
+(deftest ^{:doc "doctest"} some-test
+  (is (= 1 2)))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]