From: Yuan Fu Date: Tue, 25 Oct 2022 21:26:41 +0000 (-0700) Subject: Fix treesit-language-at X-Git-Tag: emacs-29.0.90~1789 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=e5043db2f1f3d0ce6618eb45419e85f0d58fbf19;p=emacs.git 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. --- diff --git a/doc/lispref/parsing.texi b/doc/lispref/parsing.texi index bd803579579..3648ad2f26f 100644 --- a/doc/lispref/parsing.texi +++ b/doc/lispref/parsing.texi @@ -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 diff --git a/lisp/treesit.el b/lisp/treesit.el index 86cff52af24..2200b23ce71 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -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)