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

From: Theodor Thornhill <[email-masked]>
Date: Fri, 02 Dec 2022 21:24:13 +0100

Daniel Martín <[email-masked]> writes:

> Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife
> of text editors" <[email-masked]> writes:
>
>>>
>>> Why in lisp.el? we are talking about a feature of C-like languages.  The
>>> current binding of "C-c C-q" is in cc-cmds.el, so what I had in mind is to
>>> have its counterpart in c-ts-mode.el.
>>
>> Something like this?
>
> Thanks, some comments below:
>

Thanks for looking!

>>
>> From 26a8780950017a911bac7290366da05e0e35f13f Mon Sep 17 00:00:00 2001
>> From: Theodor Thornhill <[email-masked]>
>> Date: Fri, 2 Dec 2022 16:05:35 +0100
>> Subject: [PATCH] Add c-ts-mode--indent-defun
>>
>> Add in this function to mimic 'c-indent-defun'
>>
>> * lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-defun): New function.
>> (c-ts-mode-map): New mode map that uses said function.
>> ---
>>  lisp/progmodes/c-ts-mode.el | 18 +++++++++++++++++-
>>  1 file changed, 17 insertions(+), 1 deletion(-)
>>
>> diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
>> index fcabb5beac..3171600901 100644
>> --- a/lisp/progmodes/c-ts-mode.el
>> +++ b/lisp/progmodes/c-ts-mode.el
>> @@ -518,9 +518,25 @@ c-ts-mode--end-of-defun
>>        (if (looking-at "\\s<\\|\n")
>>  	  (forward-line 1)))))
>>  
>> +(defun c-ts-mode--indent-defun ()
>
> This should be public: c-ts-mode-indent-defun
>

Yeah.

>> +  "Indent the current top-level declaration syntactically.
>> +
>> +`treesit-defun-type-regexp' defines what constructs to indent."
>> +  (interactive)
>
> (interactive "*") will handle read-only buffers a bit better.
>

I was wondering about that, but I couldn't really find any situation
that gave any difference.  But I've added it now.

>> +  (save-excursion
>> +    (mark-defun)
>> +    (indent-region (region-beginning) (region-end))))
>
> Nit: Once you call (mark-defun), you can call
>
> (indent-region (point) (mark))
>
> which should be more efficient than calling (region-beginning) or
> (region-end).

Right - thanks.  However, this makes me wonder - should we really be
setting mark here? I see that c-indent-defun does not, and it feels
weird that indenting adds to the mark ring.  What do you think?  My
first patch used

(indent-region
  (treesit-node-start node)
  (treesit-node-end node))

Which behaves similarly to c-indent-defun.

See attached patch.

Thanks,

Theo

>From 9c22569f7a98c9fd671664e0834bd079e8f20bd3 Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <[email-masked]>
Date: Fri, 2 Dec 2022 16:05:35 +0100
Subject: [PATCH] Add c-ts-mode-indent-defun

Add in this function to mimic 'c-indent-defun'

* lisp/progmodes/c-ts-mode.el (c-ts-mode-indent-defun): New function.
(c-ts-mode-map): New mode map that uses said function.
---
 lisp/progmodes/c-ts-mode.el | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index fcabb5beac..677ff07a2d 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -518,9 +518,25 @@ c-ts-mode--end-of-defun
       (if (looking-at "\\s<\\|\n")
 	  (forward-line 1)))))
 
+(defun c-ts-mode-indent-defun ()
+  "Indent the current top-level declaration syntactically.
+
+`treesit-defun-type-regexp' defines what constructs to indent."
+  (interactive "*")
+  (save-excursion
+    (mark-defun)
+    (indent-region (point) (mark))))
+
+(defvar-keymap c-ts-mode-map
+  :doc "Keymap for the C language with tree-sitter"
+  :parent prog-mode-map
+  "C-c C-q" #'c-ts-mode-indent-defun)
+
 ;;;###autoload
 (define-derived-mode c-ts-base-mode prog-mode "C"
-  "Major mode for editing C, powered by tree-sitter."
+  "Major mode for editing C, powered by tree-sitter.
+
+\\{c-ts-mode-map}"
   :syntax-table c-ts-mode--syntax-table
 
   ;; Navigation.
-- 
2.34.1