[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
master 05ab13ebc72 1/3: Add keyword :reversed to treesit-font-lock-rules
From: |
Yuan Fu |
Subject: |
master 05ab13ebc72 1/3: Add keyword :reversed to treesit-font-lock-rules |
Date: |
Fri, 20 Dec 2024 03:53:09 -0500 (EST) |
branch: master
commit 05ab13ebc7237bcf23bc84a6a345d0b563404c2d
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
Add keyword :reversed to treesit-font-lock-rules
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.
---
doc/lispref/modes.texi | 6 +++++-
lisp/treesit.el | 39 +++++++++++++++++++++++++++++++--------
2 files changed, 36 insertions(+), 9 deletions(-)
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index 2631769c51d..73edb688c85 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -4378,6 +4378,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.
@@ -4461,6 +4463,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
@@ -4471,7 +4474,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
diff --git a/lisp/treesit.el b/lisp/treesit.el
index 9db3d57b6e9..7d09934b3e6 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -866,7 +866,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.
@@ -880,7 +880,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.
@@ -900,6 +903,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)))
@@ -1030,6 +1037,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.
@@ -1064,6 +1073,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
@@ -1102,6 +1112,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)))
@@ -1116,12 +1133,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))))
@@ -1190,9 +1209,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)
@@ -1200,7 +1221,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))))))