Fix treesit-language-at

* lisp/treesit.el (treesit-language-at-point-function): New local
variable.
(treesit-language-at): Change to use
treesit-language-at-point-function rather than trying each parser
one-by-one.
* doc/lispref/parsing.texi (Multiple Languages): Update manual.
This commit is contained in:
Yuan Fu 2022-10-25 14:26:41 -07:00
parent 7c5d434833
commit e5043db2f1
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
2 changed files with 30 additions and 14 deletions

View file

@ -1407,13 +1407,6 @@ Like other query functions, this function raises the
@code{treesit-query-error} error if @var{query} is malformed.
@end defun
@defun treesit-language-at pos
This function tries to figure out which language is responsible for
the text at buffer position @var{pos}. It goes over each parser in
@code{(treesit-parser-list)} to find a parser whose ranges cover
@var{pos}.
@end defun
@defvar treesit-range-functions
This variable holds the list of range functions. Font-locking and
indenting code use functions in this list to set correct ranges for
@ -1440,6 +1433,19 @@ before using any parser. Each range function in
@var{start} and @var{end} are passed to each range function.
@end defun
@vindex treesit-language-at-point-function
@defun treesit-language-at pos
This function tries to figure out which language is responsible for
the text at buffer position @var{pos}. Under the hood it just calls
@code{treesit-language-at-point-function}.
Various Lisp programs use this function. For example, the indentation
program uses this function to determine which language's rule to use
in a multi-language buffer. So it is important to provide
@code{treesit-language-at-point-function} for a multi-language major
mode.
@end defun
@heading An example
Normally, in a set of languages that can be mixed together, there is a

View file

@ -88,11 +88,18 @@ Return the root node of the syntax tree."
(treesit-parser-root-node
(treesit-parser-create language))))
(defvar-local treesit-language-at-point-function nil
"A function that returns the language at point.
This is used by `treesit-language-at', which is used by various
functions to determine which parser to use at point.
The function is called with the position of point.")
(defun treesit-language-at (pos)
"Return the language used at position POS."
(cl-loop for parser in (treesit-parser-list)
if (treesit-node-on pos pos parser)
return (treesit-parser-language parser)))
"Return the language at POS.
Assumes parser ranges are up-to-date."
(when treesit-language-at-point-function
(funcall treesit-language-at-point-function pos)))
(defun treesit-set-ranges (parser-or-lang ranges)
"Set the ranges of PARSER-OR-LANG to RANGES."
@ -790,9 +797,12 @@ of the current line.")
(skip-chars-forward " \t")
(point)))
(smallest-node
(cl-loop for parser in (treesit-parser-list)
for node = (treesit-node-at bol parser)
if node return node))
(cond ((null (treesit-parser-list)) nil)
((eq 1 (length (treesit-parser-list)))
(treesit-node-at bol))
((treesit-language-at (point))
(treesit-node-at bol (treesit-language-at (point))))
(t (treesit-node-at bol))))
(node (treesit-parent-while
smallest-node
(lambda (node)