[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)))