Subject: bug#59662: 29.0.50; [PATCH] Add treesit--indent-defun

From: Dmitry Gutov <[email-masked]>
Date: Thu, 8 Dec 2022 03:37:54 +0200

On 03/12/2022 19:54, Eli Zaretskii wrote:
>> paredit-reindent-defun, like I described, does all that too. But when
>> outside strings and comments, it reindents the current defun.
> So maybe paredit-reindent-defun doesn't need any fixes, but using it as a
> role model for the C-like languages is not TRT, since in C these are two
> separate commands with two different key bindings.

It's not a given that the current state of things must automatically be 
optimal. But of course I can't vouch whether this behavior is optimal 
for every language.

And major modes will continue to be able to rebind these key sequences.

>> AFAICT, these behaviors are quite compatible. But paredit's binding
>> seems to be useful in more contexts.
> I'm fine with trying something like that on master, to see whether users
> like this conflation, but not on the release branch.

Here's a patch that people can try. From my brief testing, seems useful 
enough. I suppose some might dislike it, though, in some codebases where 
the methods/functions are consistently longer than a screenful. I do 
like this binding in Emacs Lisp too, though.

diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index 58cb48f182..46bacea737 100644
--- a/lisp/progmodes/prog-mode.el
+++ b/lisp/progmodes/prog-mode.el
@@ -102,7 +102,8 @@ prog-context-menu
 
 (defvar-keymap prog-mode-map
   :doc "Keymap used for programming modes."
-  "C-M-q" #'prog-indent-sexp)
+  "C-M-q" #'prog-indent-sexp
+  "M-q" #'prog-reindent-defun)
 
 (defvar prog-indentation-context nil
   "When non-nil, provides context for indenting embedded code chunks.
@@ -144,6 +145,26 @@ prog-first-column
   "Return the indentation column normally used for top-level constructs."
   (or (car prog-indentation-context) 0))
 
+(defun prog-reindent-defun (&optional argument)
+  "Refill paragraph or reindent the definition that the point is on.
+
+If the point is in a string, or in a comment, or there is a
+comment on the current line, fill the paragraph that the point is
+in or is on the same line.
+
+Otherwise, reindent the definition around or below point."
+  (interactive "P")
+  (save-excursion
+    (if (or (nth 8 (syntax-ppss))
+            (re-search-forward comment-start-skip (line-end-position) t))
+        (if (memq fill-paragraph-function '(t nil))
+            (lisp-fill-paragraph argument)
+          (funcall fill-paragraph-function argument))
+      (end-of-defun)
+      (let ((end (point)))
+        (beginning-of-defun)
+        (indent-region (point) end)))))
+
 (defvar-local prettify-symbols-alist nil
   "Alist of symbol prettifications.
 Each element looks like (SYMBOL . CHARACTER), where the symbol