Pass region start and end to tree-sitter fontification functions

* doc/lispref/modes.texi (Parser-based Font Lock): Update manual.
* lisp/progmodes/js.el (js--fontify-template-string)
* lisp/progmodes/python.el (python--treesit-fontify-string): Update
function to only fontify within the region.
* lisp/treesit.el (treesit-font-lock-rules): Update docstring.
(treesit-font-lock-fontify-region): Pass START and END to
fontification functions.
This commit is contained in:
Yuan Fu 2022-11-02 17:03:03 -07:00
parent f331be1f07
commit 69ab588bb5
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
4 changed files with 41 additions and 28 deletions

View file

@ -3979,13 +3979,15 @@ with that face.
@findex treesit-fontify-with-override
Capture names can also be function names, in which case the function
is called with 2 arguments: @var{node} and @var{override}, where
@var{node} is the node itself, and @var{override} is the override
property of the rule which captured this node. (If this function
wants to respect the @var{override} argument, it can use
@code{treesit-fontify-with-override}.) Beyond the 2 arguments
presented, this function should accept more arguments as optional
arguments for future extensibility.
is called with 4 arguments: @var{node} and @var{override}, @var{start}
and @var{end}, where @var{node} is the node itself, @var{override} is
the override property of the rule which captured this node, and
@var{start} and @var{end} limits the region in which this function
should fontify. (If this function wants to respect the @var{override}
argument, it can use @code{treesit-fontify-with-override}.)
Beyond the 4 arguments presented, this function should accept more
arguments as optional arguments for future extensibility.
If a capture name is both a face and a function, the face takes
priority. If a capture name is neither a face nor a function, it is

View file

@ -3573,9 +3573,10 @@ This function is intended for use in `after-change-functions'."
@font-lock-constant-face)))
"Tree-sitter font-lock settings.")
(defun js--fontify-template-string (node override &rest _)
(defun js--fontify-template-string (node override start end &rest _)
"Fontify template string but not substitution inside it.
BEG, END, NODE refers to the template_string node.
NODE is the template_string node. START and END marks the region
to be fontified.
OVERRIDE is the override flag described in
`treesit-font-lock-rules'."
@ -3585,16 +3586,17 @@ OVERRIDE is the override flag described in
;; closing "`". That's why we have to track BEG instead of just
;; fontifying each child.
(let ((child (treesit-node-child node 0))
(beg (treesit-node-start node)))
(font-beg (treesit-node-start node)))
(while child
(if (equal (treesit-node-type child) "template_substitution")
(let ((font-end (if (equal (treesit-node-type child)
"template_substitution")
(treesit-node-start child)
(treesit-node-end child))))
(setq font-beg (max beg font-beg))
(when (< font-beg end)
(treesit-fontify-with-override
beg (treesit-node-start child)
'font-lock-string-face override)
(treesit-fontify-with-override
beg (treesit-node-end child)
'font-lock-string-face override))
(setq beg (treesit-node-end child)
font-beg font-end 'font-lock-string-face override)))
(setq font-beg (treesit-node-end child)
child (treesit-node-next-sibling child)))))
(defun js-treesit-current-defun ()

View file

@ -1015,11 +1015,12 @@ It makes underscores and dots word constituent chars.")
"VMSError" "WindowsError"
))
(defun python--treesit-fontify-string (node override &rest _)
(defun python--treesit-fontify-string (node override start end &rest _)
"Fontify string.
NODE is the leading quote in the string. Do not fontify the initial
f for f-strings. OVERRIDE is the override flag described in
`treesit-font-lock-rules'."
NODE is the leading quote in the string. Do not fontify the
initial f for f-strings. OVERRIDE is the override flag described
in `treesit-font-lock-rules'. START and END marks the region to
be fontified."
(let* ((string (treesit-node-parent node))
(string-beg (treesit-node-start string))
(string-end (treesit-node-end string))
@ -1033,7 +1034,8 @@ f for f-strings. OVERRIDE is the override flag described in
'font-lock-string-face)))
(when (eq (char-after string-beg) ?f)
(cl-incf string-beg))
(treesit-fontify-with-override string-beg string-end face override)))
(treesit-fontify-with-override
(max start string-beg) (min end string-end) face override)))
(defvar python--treesit-settings
(treesit-font-lock-rules

View file

@ -502,11 +502,18 @@ Other keywords include:
Capture names in QUERY should be face names like
`font-lock-keyword-face'. The captured node will be fontified
with that face. Capture names can also be function names, in
which case the function should have a signature (NODE OVERRIDE
&rest _), where NODE is the tree-sitter node object, and OVERRIDE
is the override option of that rule. This function should accept
more arguments as optional arguments for future extensibility.
with that face.
Capture names can also be function names, in which case the
function should have a signature
(NODE OVERRIDE START END &rest _)
where NODE is the tree-sitter node object, OVERRIDE is the
override option of that rule, and START and END marks the region
to be fontified. This function should accept more arguments as
optional arguments for future extensibility. And this function
shouldn't fontify text outside START and END.
If a capture name is both a face and a function, the face takes
priority. If a capture name is not a face name nor a function
@ -754,7 +761,7 @@ If LOUDLY is non-nil, display some debugging information."
(max node-start start) (min node-end end)
face override))
((functionp face)
(funcall face node override)))
(funcall face node override start end)))
;; Don't raise an error if FACE is neither a face nor
;; a function. This is to allow intermediate capture
;; names used for #match and #eq.