]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve 'treesit-outline-search'.
authorJuri Linkov <juri@linkov.net>
Wed, 9 Apr 2025 17:40:09 +0000 (20:40 +0300)
committerEshel Yaron <me@eshelyaron.com>
Fri, 11 Apr 2025 11:32:13 +0000 (13:32 +0200)
* lisp/treesit.el (treesit-outline-search): Remove
temporary arg 'recursive'.  Use iteration to visit
more ranges until the next outline heading is found.

* lisp/progmodes/php-ts-mode.el (php-ts-mode):
Set 'treesit-outline-predicate' explicitly.

(cherry picked from commit fa247a24a5ec9cf10865f0ac3711eddfd0ad3546)

lisp/progmodes/php-ts-mode.el
lisp/treesit.el

index de99c0462a3647cd35a2719c6d2d9acef10e9cab..cc5f02a74c2c2c5a0f2a44910267f56b577e084b 100644 (file)
@@ -1519,7 +1519,7 @@ Depends on `c-ts-common-comment-setup'."
     (setq-local electric-indent-chars
                 (append "{}():;," electric-indent-chars))
 
-    ;; Imenu/Which-function/Outline
+    ;; Imenu/Which-function
     (setq-local treesit-simple-imenu-settings
                 '(("Class" "\\`class_declaration\\'" nil nil)
                   ("Enum" "\\`enum_declaration\\'" nil nil)
@@ -1531,6 +1531,16 @@ Depends on `c-ts-common-comment-setup'."
                   ("Variable" "\\`variable_name\\'" nil nil)
                   ("Constant" "\\`const_element\\'" nil nil)))
 
+    ;; Outline
+    (setq-local treesit-outline-predicate
+                (rx bos (or "class_declaration"
+                            "function_definition"
+                            "interface_declaration"
+                            "method_declaration"
+                            "namespace_definition"
+                            "trait_declaration")
+                    eos))
+
     ;; Font-lock.
     (setq-local treesit-font-lock-settings
                 (append (php-ts-mode--font-lock-settings)
index 851c7b3e3da26a1787441264a29c47f4e1cbf4b1..5d2e26c7368f9526679f0bef433eb8be3c99a154 100644 (file)
@@ -3978,7 +3978,7 @@ this variable takes priority.")
     (or (and current-valid current)
         (and next-valid (treesit-thing-at next pred)))))
 
-(defun treesit-outline-search (&optional bound move backward looking-at recursive)
+(defun treesit-outline-search (&optional bound move backward looking-at)
   "Search for the next outline heading in the syntax tree.
 For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
 `outline-search-function'."
@@ -3997,48 +3997,55 @@ For BOUND, MOVE, BACKWARD, LOOKING-AT, see the descriptions in
               (if (eq (point) (pos-bol))
                   (if (bobp) (point) (1- (point)))
                 (pos-eol))))
-           (pred (if treesit-aggregated-outline-predicate
-                     (alist-get (treesit-language-at (or bob-pos pos))
-                                treesit-aggregated-outline-predicate)
-                   treesit-outline-predicate))
+           (pred (unless bob-pos
+                   (if treesit-aggregated-outline-predicate
+                       (alist-get (treesit-language-at pos)
+                                  treesit-aggregated-outline-predicate)
+                     treesit-outline-predicate)))
            (found (or bob-pos
                       (treesit-navigate-thing pos (if backward -1 1) 'beg pred)))
-           (closest (unless bob-pos
+           (closest (when (and treesit-aggregated-outline-predicate (not bob-pos))
                       (if backward
                           (previous-single-char-property-change pos 'treesit-parser)
                         (next-single-char-property-change pos 'treesit-parser)))))
 
-      ;; Handle multi-language modes
-      (if (and closest
-               (not (eq closest (if backward (point-min) (point-max))))
-               (not recursive)
-               (or
-                ;; Possibly was inside the local parser, and when can't find
-                ;; more matches inside it then need to go over the closest
-                ;; parser boundary to the primary parser.
-                (not found)
-                ;; Possibly skipped the local parser, either while navigating
-                ;; inside the primary parser, or inside a local parser
-                ;; interspersed by ranges of other local parsers, e.g.
-                ;; <html><script>|</script><style/><script/></html>
-                (if backward (> closest found) (< closest found))))
-          (progn
-            (goto-char (if backward
-                           (max (point-min) (1- closest))
-                         (min (point-max) (1+ closest))))
-            (treesit-outline-search bound move backward nil 'recursive))
-
-        (if found
-            (if (or (not bound) (if backward (>= found bound) (<= found bound)))
-                (progn
-                  (goto-char found)
-                  (goto-char (pos-bol))
-                  (set-match-data (list (point) (pos-eol)))
-                  t)
-              (when move (goto-char bound))
-              nil)
-          (when move (goto-char (or bound (if backward (point-min) (point-max)))))
-          nil)))))
+      ;; Handle multi-language modes.
+      (while (and closest
+                  (not (eq closest (if backward (point-min) (point-max))))
+                  (or
+                   ;; Possibly was inside the local parser, and when can't find
+                   ;; more matches inside it then need to go over the closest
+                   ;; parser boundary to the primary parser, and search again.
+                   (not found)
+                   ;; Possibly skipped the local parser, either while navigating
+                   ;; inside the primary parser, or inside a local parser
+                   ;; interspersed by ranges of other local parsers, e.g.
+                   ;; <html><script>|</script><style/><script/></html>
+                   (if backward (> closest found) (< closest found))))
+        (goto-char (if backward
+                       (max (point-min) (1- closest))
+                     (min (point-max) (1+ closest))))
+        (setq pos (if (eq (point) (pos-bol))
+                      (if (bobp) (point) (1- (point)))
+                    (pos-eol))
+              pred (alist-get (treesit-language-at pos)
+                              treesit-aggregated-outline-predicate)
+              found (treesit-navigate-thing pos (if backward -1 1) 'beg pred)
+              closest (if backward
+                          (previous-single-char-property-change pos 'treesit-parser)
+                        (next-single-char-property-change pos 'treesit-parser))))
+
+      (if found
+          (if (or (not bound) (if backward (>= found bound) (<= found bound)))
+              (progn
+                (goto-char found)
+                (goto-char (pos-bol))
+                (set-match-data (list (point) (pos-eol)))
+                t)
+            (when move (goto-char bound))
+            nil)
+        (when move (goto-char (or bound (if backward (point-min) (point-max)))))
+        nil))))
 
 (defun treesit-outline-level ()
   "Return the depth of the current outline heading."