]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new variable 'up-list-function' for 'treesit-up-list'
authorJuri Linkov <juri@linkov.net>
Sun, 29 Dec 2024 17:57:28 +0000 (19:57 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sat, 4 Jan 2025 20:25:07 +0000 (21:25 +0100)
* lisp/emacs-lisp/lisp.el (up-list-function): New variable (bug#73404).
(up-list-default-function): New function.
(up-list): Split part to 'up-list-default-function'.

* lisp/treesit.el (treesit-up-list): New function.
(treesit-major-mode-setup): Set 'up-list-function' to
'treesit-up-list'.

(cherry picked from commit ec8dd27f008bca810209354a189d241479fe4d32)

etc/NEWS
lisp/emacs-lisp/lisp.el
lisp/treesit.el

index 68f3892fdb63fb4d3a7ad856b7f475ff82cd8d66..f678751b2f3742fcf19d312dfa1156abc62c369c 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -852,6 +852,11 @@ Tree-sitter conditionally sets 'down-list-function' for major modes
 that have defined 'sexp-list' in 'treesit-thing-settings' to enable
 the 'down-list' motion command.
 
+*** New function 'treesit-up-list'.
+Tree-sitter conditionally sets 'up-list-function' for major modes
+that have defined 'sexp-list' in 'treesit-thing-settings' to enable
+the 'up-list' motion command.
+
 +++
 *** New function 'treesit-language-display-name'.
 This new function returns the display name of a language given the
index f61464054163c634c921a6456f29aaf62f186078..3a94095b966fd0217a942e60df3e3647203d704b 100644 (file)
@@ -239,6 +239,10 @@ On error, location of point is unspecified."
   (interactive "^p\nd\nd")
   (up-list (- (or arg 1)) escape-strings no-syntax-crossing))
 
+(defvar up-list-function nil
+  "If non-nil, `up-list' delegates to this function.
+Should take the same arguments and behave similarly to `up-list'.")
+
 (defun up-list (&optional arg escape-strings no-syntax-crossing)
   "Move forward out of one level of parentheses.
 This command will also work on other parentheses-like expressions
@@ -255,6 +259,12 @@ end of a list broken across multiple strings.
 
 On error, location of point is unspecified."
   (interactive "^p\nd\nd")
+  (if up-list-function
+      (funcall up-list-function arg escape-strings no-syntax-crossing)
+    (up-list-default-function arg escape-strings no-syntax-crossing)))
+
+(defun up-list-default-function (&optional arg escape-strings no-syntax-crossing)
+  "Default function for `up-list-function'."
   (or arg (setq arg 1))
   (let ((inc (if (> arg 0) 1 -1))
         (pos nil))
index 975f9e5c89014d839b26c0cfd299bb4dab36fb40..84c29981f50eb884b3df652433539aee75826d5f 100644 (file)
@@ -2563,6 +2563,33 @@ ARG is described in the docstring of `down-list'."
         (if pos (goto-char pos) (treesit--scan-error pred arg)))
       (setq arg (- arg inc)))))
 
+(defun treesit-up-list (&optional arg _escape-strings _no-syntax-crossing)
+  "Move forward out of one level of parentheses.
+What constitutes a level of parentheses is determined by
+`sexp-list' in `treesit-thing-settings' that usually defines
+parentheses-like expressions.
+
+This command is the tree-sitter variant of `up-list'
+redefined by the variable `up-list-function'.
+
+ARG is described in the docstring of `up-list'."
+  (interactive "^p")
+  (let* ((pred 'sexp-list)
+         (arg (or arg 1))
+         (inc (if (> arg 0) 1 -1)))
+    (while (/= arg 0)
+      (let ((node (treesit-thing-at (point) pred)))
+        (while (and node (eq (point) (if (> arg 0)
+                                         (treesit-node-end node)
+                                       (treesit-node-start node))))
+          (setq node (treesit-parent-until node pred)))
+        (if node
+            (goto-char (if (> arg 0)
+                           (treesit-node-end node)
+                         (treesit-node-start node)))
+          (user-error "At top level")))
+      (setq arg (- arg inc)))))
+
 (defun treesit-transpose-sexps (&optional arg)
   "Tree-sitter `transpose-sexps' function.
 ARG is the same as in `transpose-sexps'.
@@ -3489,7 +3516,8 @@ before calling this function."
   (when (treesit-thing-defined-p 'sexp-list nil)
     (setq-local forward-sexp-function #'treesit-forward-sexp-list)
     (setq-local forward-list-function #'treesit-forward-list)
-    (setq-local down-list-function #'treesit-down-list))
+    (setq-local down-list-function #'treesit-down-list)
+    (setq-local up-list-function #'treesit-up-list))
 
   (when (treesit-thing-defined-p 'sentence nil)
     (setq-local forward-sentence-function #'treesit-forward-sentence))