From 3d69d7cabb9718f53b5703572a064a56089e79bd Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sat, 22 Feb 2025 21:52:39 +0200 Subject: [PATCH] * lisp/treesit.el (treesit-up-list, treesit-outline-level): Improve. Try to get the parent parser host node that contains the embedded parser and continue the search from it (bug#76398). (cherry picked from commit 1ffa0521131c20edbbcba84765870f01411d039e) --- doc/lispref/modes.texi | 6 +++--- lisp/treesit.el | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/doc/lispref/modes.texi b/doc/lispref/modes.texi index 8c902d6a935..844dcc0e79a 100644 --- a/doc/lispref/modes.texi +++ b/doc/lispref/modes.texi @@ -3131,8 +3131,8 @@ It's required in both cases: whether you define @code{outline-regexp} or @code{outline-search-function}. @end defvar -If built with tree-sitter, Emacs can automatically use -Outline minor mode if the major mode sets the following variable. +If built with tree-sitter, Emacs can automatically use Outline +minor mode if the major mode sets one of the following variables. @defvar treesit-outline-predicate This variable instructs Emacs how to find lines with outline headings. @@ -3142,7 +3142,7 @@ It should be a predicate that matches the node on the heading line. @defvar treesit-aggregated-outline-predicate This variable allows major modes to configure outlines for multiple languages. Its value is an alist mapping language symbols to outline -headings of the form described above for the value of +headings as described above for the value of @code{treesit-outline-predicate}. If this variable is non-@code{nil}, it overrides diff --git a/lisp/treesit.el b/lisp/treesit.el index 4d8f92e9bd7..3e9a17ead67 100644 --- a/lisp/treesit.el +++ b/lisp/treesit.el @@ -2830,6 +2830,15 @@ ARG is described in the docstring of `up-list'." (treesit-node-end parent) (treesit-node-start parent)))) (setq parent (treesit-parent-until parent pred))) + + (when-let* ((_ (null parent)) + (parser (treesit-node-parser (treesit-node-at (point)))) + (_ (not (eq parser treesit-primary-parser))) + (guest-root-node (treesit-parser-root-node parser))) + ;; Continue from the host node that contains the guest parser. + (setq parent (treesit-thing-at + (- (treesit-node-start guest-root-node) 2) pred))) + (or (when (and default-pos (or (null parent) (if (> arg 0) @@ -3709,7 +3718,7 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in "Return the depth of the current outline heading." (let* ((node (treesit-outline--at-point)) (level 1) - (parser (when treesit-aggregated-outline-predicate + (parser (when (and treesit-aggregated-outline-predicate node) (treesit-node-parser node))) (pred (if treesit-aggregated-outline-predicate (alist-get (treesit-language-at (point)) @@ -3717,13 +3726,12 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in treesit-outline-predicate))) (while (setq node (treesit-parent-until node pred)) (setq level (1+ level))) - (when-let* ((_ parser) + (when-let* ((_ (and parser (not (eq parser treesit-primary-parser)))) + (guest-root-node (treesit-parser-root-node parser)) (host-lang (treesit-parser-language treesit-primary-parser)) - (_ (not (eq (treesit-language-at (point)) host-lang))) (host-pred (alist-get host-lang treesit-aggregated-outline-predicate))) - ;; Now need to break out of embedded confinement - ;; and get the host node that contains the guest ranges - (setq node (treesit-parser-root-node parser)) + ;; Continue from the host node that contains the guest parser. + (setq node (treesit-node-at (- (treesit-node-start guest-root-node) 2))) (while (setq node (treesit-parent-until node host-pred)) (setq level (1+ level)))) level)) -- 2.39.5