]> git.eshelyaron.com Git - emacs.git/commitdiff
Add keyword :reversed to treesit-font-lock-rules
authorYuan Fu <casouri@gmail.com>
Fri, 20 Dec 2024 03:02:59 +0000 (19:02 -0800)
committerEshel Yaron <me@eshelyaron.com>
Mon, 23 Dec 2024 15:17:51 +0000 (16:17 +0100)
This keyword will be useful for implementing
string-interpolation feature.

* doc/lispref/modes.texi (Parser-based Font Lock): Document the
new keyword.
* lisp/treesit.el (treesit-font-lock-settings): Document.
(treesit-font-lock-setting-reversed): New function.
(treesit-font-lock-rules): Add new keyword.
(treesit-font-lock-recompute-features): Handle new keyword.

(cherry picked from commit 05ab13ebc7237bcf23bc84a6a345d0b563404c2d)

doc/lispref/modes.texi
lisp/treesit.el

index 6662da72d6ded4c675320cc32fc9b08f9565a203..6e44b9674c2f8a5e51f80c65be5613c2f082650e 100644 (file)
@@ -4342,6 +4342,8 @@ Other keywords are optional:
 @item @tab @code{append} @tab Append the new face to existing ones
 @item @tab @code{prepend} @tab Prepend the new face to existing ones
 @item @tab @code{keep} @tab Fill-in regions without an existing face
+@item @code{:reversed} @tab @code{t}
+@tab Enable @var{query} when @var{feature} is not in the feature list.
 @item @code{:default-language} @tab @var{language}
 @tab Every @var{query} after this keyword will use @var{language}
 by default.
@@ -4425,6 +4427,7 @@ For this variable to take effect, a Lisp program should call
 @findex treesit-font-lock-setting-feature
 @findex treesit-font-lock-setting-enable
 @findex treesit-font-lock-setting-override
+@findex treesit-font-lock-setting-reversed
 @defvar treesit-font-lock-settings
 A list of settings for tree-sitter based font lock.  The exact format of
 each individual setting is considered internal.  One should always use
@@ -4435,7 +4438,8 @@ the setting's query, feature, enable flag and override flag:
 @code{treesit-font-lock-setting-query},
 @code{treesit-font-lock-setting-feature},
 @code{treesit-font-lock-setting-enable},
-@code{treesit-font-lock-setting-override}.
+@code{treesit-font-lock-setting-override},
+@code{treesit-font-lock-setting-reversed}.
 
 @c Because the format is internal, we don't document them here.  Though
 @c we do have it explained in the docstring.  We also expose the fact
index 0fa0862f441dffc86c258f973d21c7ac7c34523d..98903dffa69c1e1c13573b52781775cc4907b74f 100644 (file)
@@ -865,7 +865,7 @@ debugging:
 
 Currently each SETTING has the form:
 
-    (QUERY ENABLE FEATURE OVERRIDE)
+    (QUERY ENABLE FEATURE OVERRIDE REVERSE)
 
 QUERY must be a compiled query.  See Info node `(elisp)Pattern
 Matching' for how to write a query and compile it.
@@ -879,7 +879,10 @@ which features are enabled with `treesit-font-lock-level' and
 
 OVERRIDE is the override flag for this query.  Its value can be
 t, nil, append, prepend, keep.  See more in
-`treesit-font-lock-rules'.")
+`treesit-font-lock-rules'.
+
+If REVERSED is t, enable the QUERY when FEATURE is not in the feature
+list.")
 
 ;; Follow cl-defstruct naming conventions, in case we use cl-defstruct
 ;; in the future.
@@ -899,6 +902,10 @@ t, nil, append, prepend, keep.  See more in
   "Return the OVERRIDE flag of SETTING in `treesit-font-lock-settings'."
   (nth 3 setting))
 
+(defsubst treesit-font-lock-setting-reversed (setting)
+  "Return the REVERSED flag of SETTING in `treesit-font-lock-settings'."
+  (nth 4 setting))
+
 (defsubst treesit--font-lock-setting-clone-enable (setting)
   "Return enabled SETTING."
   (let ((new-setting (copy-tree setting)))
@@ -1029,6 +1036,8 @@ Other keywords include:
              `append'   Append the new face to existing ones.
              `prepend'  Prepend the new face to existing ones.
              `keep'     Fill-in regions without an existing face.
+  :reversed  t          Enable the query only if the feature is
+                        NOT in feature list.
   :default-language  LANGUAGE  Every QUERY after this keyword
                                will use LANGUAGE by default.
 
@@ -1063,6 +1072,7 @@ name, it is ignored."
           ;; DEFAULT-LANGUAGE will be chosen when current-language is
           ;; not set.
           default-language
+          current-reversed
           ;; The list this function returns.
           (result nil))
       (while query-specs
@@ -1098,6 +1108,13 @@ name, it is ignored."
                          `("Value of :feature should be a symbol"
                            ,var)))
                (setq current-feature var)))
+            (:reversed
+             (let ((var (pop query-specs)))
+               (when (not (memq var '(t nil)))
+                 (signal 'treesit-font-lock-error
+                         `("Value of :reversed can only be t or nil"
+                           ,var)))
+               (setq current-reversed var)))
             ;; (2) Process query.
             ((pred treesit-query-p)
              (let ((lang (or default-language current-language)))
@@ -1112,12 +1129,14 @@ name, it is ignored."
                  (push `(,(treesit-query-compile lang token)
                          t
                          ,current-feature
-                         ,current-override)
+                         ,current-override
+                         ,current-reversed)
                        result))
                ;; Clears any configurations set for this query.
                (setq current-language nil
                      current-override nil
-                     current-feature nil)))
+                     current-feature nil
+                     current-reversed nil)))
             (_ (signal 'treesit-font-lock-error
                        `("Unexpected value" ,token))))))
       (nreverse result))))
@@ -1186,9 +1205,11 @@ and leave settings for other languages unchanged."
          (additive (or add-list remove-list)))
     (cl-loop for idx = 0 then (1+ idx)
              for setting in treesit-font-lock-settings
-             for lang = (treesit-query-language (nth 0 setting))
-             for feature = (nth 2 setting)
-             for current-value = (nth 1 setting)
+             for lang = (treesit-query-language
+                         (treesit-font-lock-setting-query setting))
+             for feature = (treesit-font-lock-setting-feature setting)
+             for current-value = (treesit-font-lock-setting-enable setting)
+             for reversed = (treesit-font-lock-setting-reversed setting)
              ;; Set the ENABLE flag for the setting if its language is
              ;; relevant.
              if (or (null language)
@@ -1196,7 +1217,9 @@ and leave settings for other languages unchanged."
              do (setf (nth 1 (nth idx treesit-font-lock-settings))
                       (cond
                        ((not additive)
-                        (if (memq feature features) t nil))
+                        (if (not reversed)
+                            (if (memq feature features) t nil)
+                          (if (memq feature features) nil t)))
                        ((memq feature add-list) t)
                        ((memq feature remove-list) nil)
                        (t current-value))))))