diff --git a/lisp/treesit.el b/lisp/treesit.el index e2fdfb7c1ef..9e3c75519f9 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -226,17 +226,35 @@ is nil, try to guess the language at POS using `treesit-language-at'. If there's a local parser at POS, the local parser takes priority unless PARSER-OR-LANG is a parser, or PARSER-OR-LANG is a language and doesn't match the language of the local parser." - (let* ((root (if (treesit-parser-p parser-or-lang) - (treesit-parser-root-node parser-or-lang) - (or (when-let* ((parser - (car (treesit-local-parsers-at - pos parser-or-lang)))) - (treesit-parser-root-node parser)) - (condition-case nil - (treesit-buffer-root-node - (or parser-or-lang - (treesit-language-at pos))) - (treesit-no-parser nil))))) + (let* ((root + ;; 1. Given a parser, just use the parser's root node. + (cond ((treesit-parser-p parser-or-lang) + (treesit-parser-root-node parser-or-lang)) + ;; 2. Given a language, try local parser, then global + ;; parser. + (parser-or-lang + (let* ((local-parser (car (treesit-local-parsers-at + pos parser-or-lang))) + (global-parser (car (treesit-parser-list + nil parser-or-lang))) + (parser (or local-parser global-parser))) + (when parser + (treesit-parser-root-node parser)))) + ;; 3. No given language, try to get a language at point. + ;; If we got a language, only use parser of that + ;; language, otherwise use any parser we can find. When + ;; finding parser, try local parser first, then global + ;; parser. + (t + ;; LANG can be nil. + (let* ((lang (treesit-language-at pos)) + (local-parser (car (treesit-local-parsers-at + pos lang))) + (global-parser (car (treesit-parser-list + nil lang))) + (parser (or local-parser global-parser))) + (when parser + (treesit-parser-root-node parser)))))) (node root) (node-before root) (pos-1 (max (1- pos) (point-min)))