]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix treesit-language-at
authorYuan Fu <casouri@gmail.com>
Tue, 25 Oct 2022 21:26:41 +0000 (14:26 -0700)
committerYuan Fu <casouri@gmail.com>
Tue, 25 Oct 2022 21:26:41 +0000 (14:26 -0700)
* 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.

doc/lispref/parsing.texi
lisp/treesit.el

index bd80357957996169fd8215d220ec9a6586ba9cb9..3648ad2f26f178e401a51a799e384009aaf96b50 100644 (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
index 86cff52af244eba29a3e81be8f40235fe29be3ce..2200b23ce716ea02bf1b0810d3a5aff2b8d4201d 100644 (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)