Add tree-sitter version of prog-fill-reindent-defun (bug#78703)

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.
This commit is contained in:
Yuan Fu 2025-06-09 22:35:34 -07:00
parent 5390593c42
commit f904ff5ca2
No known key found for this signature in database
GPG key ID: 56E19BC57664A442
2 changed files with 51 additions and 12 deletions

View file

@ -166,22 +166,36 @@ instead."
(and (re-search-forward "\\s-*\\s<" (line-end-position) t)
(nth 8 (syntax-ppss))))))
(defun prog-fill-reindent-defun (&optional argument)
(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 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."
or follows point.
If JUSTIFY is non-nil (interactively, with prefix argument), justify as
well."
(interactive "P")
(save-excursion
(if (prog--text-at-point-p)
(fill-paragraph argument (region-active-p))
(beginning-of-defun)
(let ((start (point)))
(end-of-defun)
(indent-region start (point) nil)))))
(funcall prog-fill-reindent-defun-function justify))
(defun prog-first-column ()
"Return the indentation column normally used for top-level constructs."

View file

@ -58,6 +58,7 @@
(require 'cl-lib)
(require 'font-lock)
(require 'seq)
(require 'prog-mode) ; For `prog--text-at-point-p'.
;;; Function declarations
@ -3861,6 +3862,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
@ -4351,8 +4374,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'.
@ -4415,7 +4438,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