[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
feature/tree-sitter c88a1631e3 2/3: Make tree-sitter font-lock support d
From: |
Yuan Fu |
Subject: |
feature/tree-sitter c88a1631e3 2/3: Make tree-sitter font-lock support decoration levels |
Date: |
Sun, 9 Oct 2022 20:21:01 -0400 (EDT) |
branch: feature/tree-sitter
commit c88a1631e3f76926bf0fed49fa1b704d6eaf2155
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
Make tree-sitter font-lock support decoration levels
* admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html:
Update.
* admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html:
Update.
* doc/lispref/modes.texi: Mention the new :level option.
* lisp/treesit.el (treesit-font-lock-settings): Update docstring.
(treesit-font-lock-rules): Support :level. Relayout the let form.
(treesit-font-lock-fontify-region): Support :level.
---
.../html-manual/Parser_002dbased-Font-Lock.html | 9 ++++
.../html-manual/Parsing-Program-Source.html | 4 ++
doc/lispref/modes.texi | 10 ++++
lisp/treesit.el | 57 +++++++++++++++++-----
4 files changed, 67 insertions(+), 13 deletions(-)
diff --git
a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html
b/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html
index 246ebf0519..c91152edc0 100644
--- a/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html
+++ b/admin/notes/tree-sitter/html-manual/Parser_002dbased-Font-Lock.html
@@ -117,8 +117,17 @@ every query must specify the language. Other keywords are
optional:
<tr><td width="15%"></td><td width="15%"><code>keep</code></td><td
width="60%">Fill-in regions without an existing face</td></tr>
<tr><td width="15%"><code>:toggle</code></td><td
width="15%"><var>symbol</var></td><td width="60%">If non-nil, its value should
be a variable name. The variable’s value
(nil/non-nil) disables/enables the query during fontification.</td></tr>
+<tr><td width="15%"></td><td width="15%">nil</td><td width="60%">Always enable
this query.</td></tr>
+<tr><td width="15%"><code>:level</code></td><td
width="15%"><var>integer</var></td><td width="60%">If non-nil, its value should
be the decoration level for this query.
+Decoration level is controlled by
<code>font-lock-maximum-decoration</code>.</td></tr>
+<tr><td width="15%"></td><td width="15%">nil</td><td width="60%">Always enable
this query.</td></tr>
</table>
+<p>Note that a query is applied only when both <code>:toggle</code> and
+<code>:level</code> permit it. <code>:level</code> is used for global,
+coarse-grained control, whereas <code>:toggle</code> is for local,
+fine-grained control.
+</p>
<p>Capture names in <var>query</var> should be face names like
<code>font-lock-keyword-face</code>. The captured node will be fontified
with that face. Capture names can also be function names, in which
diff --git a/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html
b/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html
index 7b6e51468a..81b42f7f52 100644
--- a/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html
+++ b/admin/notes/tree-sitter/html-manual/Parsing-Program-Source.html
@@ -94,6 +94,10 @@ for this Emacs instance.
see <a href="Parser_002dbased-Font-Lock.html">Parser-based Font Lock</a>, <a
href="Parser_002dbased-Indentation.html">Parser-based Indentation</a>, and
<a href="List-Motion.html">Moving over Balanced Expressions</a>.
</p>
+<p>About naming convention: use “tree-sitter” when referring to it
as a
+noun, like <code>python-use-tree-sitter</code>, but use “treesit”
for
+prefixes, like <code>python-treesit-indent-function</code>.
+</p>
<p>To access the syntax tree of the text in a buffer, we need to first
load a language definition and create a parser with it. Next, we can
query the parser for specific nodes in the syntax tree. Then, we can
diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi
index dcc0b2958d..b1287c6ad0 100644
--- a/doc/lispref/modes.texi
+++ b/doc/lispref/modes.texi
@@ -3935,8 +3935,18 @@ every query must specify the language. Other keywords
are optional:
@item @code{:toggle} @tab @var{symbol} @tab
If non-nil, its value should be a variable name. The variable's value
(nil/non-nil) disables/enables the query during fontification.
+@item @tab nil @tab Always enable this query.
+@item @code{:level} @tab @var{integer} @tab
+If non-nil, its value should be the decoration level for this query.
+Decoration level is controlled by @code{font-lock-maximum-decoration}.
+@item @tab nil @tab Always enable this query.
@end multitable
+Note that a query is applied only when both @code{:toggle} and
+@code{:level} permit it. @code{:level} is used for global,
+coarse-grained control, whereas @code{:toggle} is for local,
+fine-grained control.
+
Capture names in @var{query} should be face names like
@code{font-lock-keyword-face}. The captured node will be fontified
with that face. Capture names can also be function names, in which
diff --git a/lisp/treesit.el b/lisp/treesit.el
index db96a89975..7132f1d5ee 100644
--- a/lisp/treesit.el
+++ b/lisp/treesit.el
@@ -289,7 +289,7 @@ should always use `treesit-font-lock-rules' to set this
variable.
Each SETTING is of form
- (LANGUAGE QUERY OVERRIDE TOGGLE)
+ (LANGUAGE QUERY OVERRIDE TOGGLE LEVEL)
Each SETTING controls one parser (often of different language).
LANGUAGE is the language symbol. See Info node `(elisp)Language
@@ -308,7 +308,11 @@ t, nil, append, prepend, keep. See more in
TOGGLE should be a variable (symbol) or nil. The variable's
value (nil/non-nil) controls whether to activate the query during
-fontification. If TOGGLE is nil, the query is always activated.")
+fontification. If TOGGLE is nil, the query is always activated.
+
+LEVEL is the decoration level of this query or nil. Decoration
+level is controlled by `font-lock-maximum-decoration'. If LEVEL
+is nil, the query is always activated.")
(defun treesit-font-lock-rules (&rest args)
"Return a value suitable for `treesit-font-lock-settings'.
@@ -344,6 +348,15 @@ include:
The value of that variable (non-nil/nil)
activates/deactivates the query during
fontification.
+ nil Always activate this query.
+ :level <integer>If non-nil, the value is the decoration
+ level of this query.
+ (See `font-lock-maximum-decoration'.)
+ nil Always activate this query.
+
+Note that a query is applied only when both :toggle and :level
+permit it. :level is used for global, coarse-grained control,
+whereas :toggle is for local, fine-grained control.
Capture names in QUERY should be face names like
`font-lock-keyword-face'. The captured node will be fontified
@@ -356,18 +369,16 @@ a capture name is not a face name nor a function name, it
is
ignored.
\(fn :KEYWORD VALUE QUERY...)"
- (let (;; Tracks the current language that following queries will
- ;; apply to.
- (current-language nil)
- ;; Tracks :override flag.
- (current-override nil)
- ;; Track :toggle flag.
- (current-toggle t)
+ (let (;; Tracks the current :language/:override/:toggle/:level value
+ ;; that following queries will apply to.
+ current-language current-override
+ current-toggle current-level
;; The list this function returns.
(result nil))
(while args
(let ((token (pop args)))
(pcase token
+ ;; (1) Process keywords.
(:language
(let ((lang (pop args)))
(when (or (not (symbolp lang)) (null lang))
@@ -393,6 +404,14 @@ ignored.
`("Value of :toggle should be a variable name"
,var)))
(setq current-toggle var)))
+ (:level
+ (let ((level (pop args)))
+ (when (not (and (integerp level) (> level 0)))
+ (signal 'treesit-font-lock-error
+ `("Value of :level should be a positive integer"
+ ,level)))
+ (setq current-level level)))
+ ;; (2) Process query.
((pred treesit-query-p)
(when (null current-language)
(signal 'treesit-font-lock-error
@@ -402,12 +421,14 @@ ignored.
(push `(,current-language
,(treesit-query-compile current-language token)
,current-override
- ,current-toggle)
+ ,current-toggle
+ ,current-level)
result))
;; Clears any configurations set for this query.
(setq current-language nil
current-override nil
- current-toggle nil))
+ current-toggle nil
+ current-level nil))
(_ (signal 'treesit-font-lock-error
`("Unexpected value" token))))))
(nreverse result)))
@@ -423,10 +444,20 @@ If LOUDLY is non-nil, message some debugging information."
(match-pattern (nth 1 setting))
(override (nth 2 setting))
(toggle (nth 3 setting))
+ (level (nth 4 setting))
(parser (treesit-parser-create language)))
(when-let ((node (treesit-node-on start end parser))
- (activate (or (null toggle)
- (symbol-value toggle))))
+ ;; Only activate this query if both :toggle and
+ ;; :level permit it.
+ (activate
+ (and (or (null toggle)
+ (symbol-value toggle))
+ (or (null level)
+ (pcase (font-lock-value-in-major-mode
+ font-lock-maximum-decoration)
+ ('t t)
+ ('nil (eq level 1))
+ (lvl (<= level lvl)))))))
(ignore activate)
(let ((captures (treesit-query-capture
node match-pattern