]> git.eshelyaron.com Git - emacs.git/commitdiff
Add tree-sitter version of prog-fill-reindent-defun (bug#78703)
authorYuan Fu <casouri@gmail.com>
Tue, 10 Jun 2025 05:35:34 +0000 (22:35 -0700)
committerEshel Yaron <me@eshelyaron.com>
Wed, 18 Jun 2025 08:02:32 +0000 (10:02 +0200)
Add a tree-sitter version of prog-fill-reindent-defun that
indents the defun that encloses point, rather than the sibling
defun after point when there is one.

* lisp/progmodes/prog-mode.el:
(prog-fill-reindent-defun): Turns into a wrapper function.
(prog-fill-reindent-defun-function): New variable.
(prog-fill-reindent-defun-default): Old prog-fill-reindent-defun
becomes this function.
* lisp/treesit.el (treesit-fill-reindent-defun): New function.
(treesit-major-mode-setup): Setup
prog-fill-reindent-defun-function.

(cherry picked from commit f904ff5ca2535356e1353e5fc95d9b0643b8570b)

lisp/progmodes/prog-mode.el
lisp/treesit.el

index 09775a55ab3044a2cda50e9d26a7d14c13d471af..d792011a2aee71c1ce5a8f9aaeb188ba43b5748c 100644 (file)
@@ -168,23 +168,37 @@ instead."
         (and (re-search-forward "\\s-*\\s<" (line-end-position) t)
              (nth 8 (syntax-ppss))))))
 
-(defun prog-fill-reindent-defun (&optional argument)
-  "Refill or reindent the paragraph or defun that contains point.
-
-If the point is in a string or a comment, fill the paragraph that
-contains point or follows point.
-
-Otherwise, reindent the function definition that contains point
-or follows point."
+(defvar prog-fill-reindent-defun-function
+  #'prog-fill-reindent-defun-default
+  "Function called by `prog-fill-reindent-defun' to do the actual work.
+It should take the same argument as `prog-fill-reindent-defun'.")
+
+(defun prog-fill-reindent-defun-default (&optional justify)
+  "Default implementation of `prog-fill-reindent-defun'.
+JUSTIFY is the same as in `fill-paragraph'."
   (interactive "P")
   (save-excursion
     (if (prog--text-at-point-p)
-        (fill-paragraph argument (region-active-p))
+        (fill-paragraph justify (region-active-p))
       (beginning-of-defun)
       (let ((start (point)))
         (end-of-defun)
         (indent-region start (point) nil)))))
 
+(defun prog-fill-reindent-defun (&optional justify)
+  "Refill or reindent the paragraph or defun that contains point.
+
+If the point is in a string or a comment, fill the paragraph that
+contains point or follows point.
+
+Otherwise, reindent the function definition that contains point
+or follows point.
+
+If JUSTIFY is non-nil (interactively, with prefix argument), justify as
+well."
+  (interactive "P")
+  (funcall prog-fill-reindent-defun-function justify))
+
 (defun prog-first-column ()
   "Return the indentation column normally used for top-level constructs."
   (or (car prog-indentation-context) 0))
index a757c0759a2c6428a998e65e21db4cb3935f6c24..1d06efb2e6d8f89d8a4b70f4b17c582af2aceda7 100644 (file)
@@ -58,6 +58,7 @@
 (require 'cl-lib)
 (require 'font-lock)
 (require 'seq)
+(require 'prog-mode) ; For `prog--text-at-point-p'.
 
 ;;; Function declarations
 
@@ -3853,6 +3854,28 @@ The delimiter between nested defun names is controlled by
       (setq node (treesit-node-parent node)))
     name))
 
+;;; Prog mode
+
+(defun treesit-fill-reindent-defun (&optional justify)
+  "Refill/reindent the paragraph/defun that contains point.
+
+This is a tree-sitter implementation of `prog-fill-reindent-defun'.
+
+`treesit-major-mode-setup' assigns this function to
+`prog-fill-reindent-defun-function' if the major mode defines the
+`defun' thing.
+
+JUSTIFY is the same as in `fill-paragraph'."
+  (interactive "P")
+  (save-excursion
+    (if (prog--text-at-point-p)
+        (fill-paragraph justify (region-active-p))
+      (let* ((treesit-defun-tactic 'parent-first)
+             (node (treesit-defun-at-point)))
+        (indent-region (treesit-node-start node)
+                       (treesit-node-end node)
+                       nil)))))
+
 ;;; Imenu
 
 (defvar treesit-simple-imenu-settings nil
@@ -4344,8 +4367,8 @@ and enable `font-lock-mode'.
 If `treesit-simple-indent-rules' is non-nil, set up indentation.
 
 If `treesit-defun-type-regexp' is non-nil or `defun' is defined
-in `treesit-thing-settings', set up `beginning-of-defun-function'
-and `end-of-defun-function'.
+in `treesit-thing-settings', set up `beginning-of-defun-function',
+`end-of-defun-function', and `prog-fill-reindent-defun-function'.
 
 If `treesit-defun-name-function' is non-nil, set up
 `add-log-current-defun'.
@@ -4408,7 +4431,9 @@ before calling this function."
     ;; the variables.  In future we should update `end-of-defun' to
     ;; work with nested defuns.
     (setq-local beginning-of-defun-function #'treesit-beginning-of-defun)
-    (setq-local end-of-defun-function #'treesit-end-of-defun))
+    (setq-local end-of-defun-function #'treesit-end-of-defun)
+    (setq-local prog-fill-reindent-defun-function
+                #'treesit-fill-reindent-defun))
   ;; Defun name.
   (when treesit-defun-name-function
     (setq-local add-log-current-defun-function