* bug#61142: Acknowledgement (29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions)
[not found] <handler.61142.B.16749811447164.ack@debbugs.gnu.org>
@ 2023-02-01 8:46 ` 太阳
2023-02-04 10:45 ` bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: 太阳 @ 2023-02-01 8:46 UTC (permalink / raw)
To: 61142
After reading treesit's manual, I found that we can use `n-p-gp` as the matcher and `grand-parent` as the anchor to match the body of `if` (and `while`, which has a similar issue).
I mean a rule looks like the following:
```
((n-p-gp nil "block" "if_statement") grand-parent java-ts-mode-indent-offset)
```
GNU bug Tracking System 在 2023年01月29日 星期日 16时33分03秒 (+08:00) 写道:
> Thank you for filing a new bug report with debbugs.gnu.org.
>
> This is an automatically generated reply to let you know your message
> has been received.
>
> Your message is being forwarded to the package maintainers and other
> interested parties for their attention; they will reply in due course.
>
> Your message has been sent to the package maintainer(s):
> bug-gnu-emacs@gnu.org
>
> If you wish to submit further information on this problem, please
> send it to 61142@debbugs.gnu.org.
>
> Please do not send mail to help-debbugs@gnu.org unless you wish
> to report a problem with the Bug-tracking system.
>
--
发送自 Vivaldi 邮件。访问 vivaldi.com 免费下载
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-01 8:46 ` bug#61142: Acknowledgement (29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions) 太阳
@ 2023-02-04 10:45 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-04 10:45 UTC (permalink / raw)
To: 太阳; +Cc: 61142
太阳 <zjyzhaojiyang@hotmail.com> writes:
> After reading treesit's manual, I found that we can use `n-p-gp` as the matcher
> and `grand-parent` as the anchor to match the body of `if` (and `while`, which
> has a similar issue).
>
> I mean a rule looks like the following:
>
> ```
> ((n-p-gp nil "block" "if_statement") grand-parent java-ts-mode-indent-offset)
> ```
>
>
Thanks! We have a mechanism in place for this, see
'c-ts-common-statement-offset' in 'c-ts-common.el'. I didn't get to it
yet, but I'll try to look at it this evening, unless you want to? See
c-ts-mode for examples of how to use it, if you're interested!
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-04 10:45 ` bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:54 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
` (2 more replies)
0 siblings, 3 replies; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 7:53 UTC (permalink / raw)
To: 太阳; +Cc: 61142
[-- Attachment #1: Type: text/plain, Size: 1098 bytes --]
Theodor Thornhill <theo@thornhill.no> writes:
> 太阳 <zjyzhaojiyang@hotmail.com> writes:
>
>> After reading treesit's manual, I found that we can use `n-p-gp` as the matcher
>> and `grand-parent` as the anchor to match the body of `if` (and `while`, which
>> has a similar issue).
>>
>> I mean a rule looks like the following:
>>
>> ```
>> ((n-p-gp nil "block" "if_statement") grand-parent java-ts-mode-indent-offset)
>> ```
>>
>>
>
>
> Thanks! We have a mechanism in place for this, see
> 'c-ts-common-statement-offset' in 'c-ts-common.el'. I didn't get to it
> yet, but I'll try to look at it this evening, unless you want to? See
> c-ts-mode for examples of how to use it, if you're interested!
>
> Theo
Hi again!
Can you test this patch for me?
@Eli: Is this ok for emacs-29? I'd love to add some test for this, but
now they are on the master branch. What is the common procedure to move
stuff from master branch to the release branch? I _can_ just add some
test to the master branch, but it would be nice to have them on emacs-29
too :-)
Theo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-c-ts-common-statement-offset-in-java-ts-mode.patch --]
[-- Type: text/x-patch, Size: 4821 bytes --]
From 18beb67646446363cec98e4074822b9fcf270d12 Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <theo@thornhill.no>
Date: Sun, 5 Feb 2023 08:49:08 +0100
Subject: [PATCH] Use c-ts-common-statement-offset in java-ts-mode
* lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): Add new
matchers to enable c-ts-common machinery.
(java-ts-mode): Add regexps.
* lisp/progmodes/c-ts-common.el (c-ts-common-statement-offset): Fix
typo.
---
lisp/progmodes/c-ts-common.el | 2 +-
lisp/progmodes/java-ts-mode.el | 34 +++++++++++++++++++++++++---------
2 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 8729cae4ba..188734badb 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -285,7 +285,7 @@ c-ts-common-statement-offset
"This anchor is used for children of a statement inside a block.
This function basically counts the number of block nodes (i.e.,
-brackets) (defined by `c-ts-mode--indent-block-type-regexp')
+brackets) (defined by `c-ts-common-indent-block-type-regexp')
between NODE and the root node (not counting NODE itself), and
multiply that by `c-ts-common-indent-offset'.
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index b9f7894095..1b6f2ba8b3 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -70,22 +70,24 @@ java-ts-mode--syntax-table
(defvar java-ts-mode--indent-rules
`((java
((parent-is "program") point-min 0)
- ((node-is "}") (and parent parent-bol) 0)
+ ((match "}" "element_value_array_initializer")
+ parent-bol 0)
+ ((node-is "}") point-min c-ts-common-statement-offset)
((node-is ")") parent-bol 0)
((node-is "]") parent-bol 0)
((and (parent-is "comment") c-ts-common-looking-at-star)
c-ts-common-comment-start-after-first-star -1)
((parent-is "comment") prev-adaptive-prefix 0)
((parent-is "text_block") no-indent)
- ((parent-is "class_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "class_body") point-min c-ts-common-statement-offset)
((parent-is "array_initializer") parent-bol java-ts-mode-indent-offset)
- ((parent-is "annotation_type_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "interface_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "constructor_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "annotation_type_body") point-min c-ts-common-statement-offset)
+ ((parent-is "interface_body") point-min c-ts-common-statement-offset)
+ ((parent-is "constructor_body") point-min c-ts-common-statement-offset)
((parent-is "enum_body_declarations") parent-bol 0)
- ((parent-is "enum_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "switch_block") parent-bol java-ts-mode-indent-offset)
- ((parent-is "record_declaration_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "enum_body") point-min c-ts-common-statement-offset)
+ ((parent-is "switch_block") point-min c-ts-common-statement-offset)
+ ((parent-is "record_declaration_body") point-min c-ts-common-statement-offset)
((query "(method_declaration (block _ @indent))") parent-bol java-ts-mode-indent-offset)
((query "(method_declaration (block (_) @indent))") parent-bol java-ts-mode-indent-offset)
((parent-is "local_variable_declaration") parent-bol java-ts-mode-indent-offset)
@@ -118,7 +120,7 @@ java-ts-mode--indent-rules
((parent-is "case_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "labeled_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "do_statement") parent-bol java-ts-mode-indent-offset)
- ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)))
+ ((parent-is "block") point-min c-ts-common-statement-offset)))
"Tree-sitter indent rules.")
(defvar java-ts-mode--keywords
@@ -300,6 +302,20 @@ java-ts-mode
(c-ts-common-comment-setup)
;; Indent.
+ (setq-local c-ts-common-indent-block-type-regexp
+ (rx (or "class_body"
+ "\\`array_initializer"
+ "annotation_type_body"
+ "interface_body"
+ "interface_constructor_body"
+ "enum_body"
+ "switch_block"
+ "record_declaration_body"
+ "block")))
+ (setq-local c-ts-common-indent-bracketless-type-regexp
+ (rx (or "if_statement" "do_statement"
+ "for_statement" "while_statement")))
+ (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
(setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
;; Electric
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 7:54 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 9:20 ` Eli Zaretskii
2023-02-05 13:09 ` bug#61142: 回复: " 赵 纪阳
2 siblings, 0 replies; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 7:54 UTC (permalink / raw)
To: 太阳; +Cc: 61142, eliz
(Actually adding Eli to Cc...)
> @Eli: Is this ok for emacs-29? I'd love to add some test for this, but
> now they are on the master branch. What is the common procedure to move
> stuff from master branch to the release branch? I _can_ just add some
> test to the master branch, but it would be nice to have them on emacs-29
> too :-)
>
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:54 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 9:20 ` Eli Zaretskii
2023-02-05 9:28 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 13:09 ` bug#61142: 回复: " 赵 纪阳
2 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2023-02-05 9:20 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142, zjyzhaojiyang
> Cc: 61142@debbugs.gnu.org
> Date: Sun, 05 Feb 2023 08:53:33 +0100
> From: Theodor Thornhill via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>
> Theodor Thornhill <theo@thornhill.no> writes:
>
> > 太阳 <zjyzhaojiyang@hotmail.com> writes:
> >
> >> After reading treesit's manual, I found that we can use `n-p-gp` as the matcher
> >> and `grand-parent` as the anchor to match the body of `if` (and `while`, which
> >> has a similar issue).
> >>
> >> I mean a rule looks like the following:
> >>
> >> ```
> >> ((n-p-gp nil "block" "if_statement") grand-parent java-ts-mode-indent-offset)
> >> ```
> >>
> >>
> >
> >
> > Thanks! We have a mechanism in place for this, see
> > 'c-ts-common-statement-offset' in 'c-ts-common.el'. I didn't get to it
> > yet, but I'll try to look at it this evening, unless you want to? See
> > c-ts-mode for examples of how to use it, if you're interested!
> >
> > Theo
>
> Hi again!
>
> Can you test this patch for me?
>
> @Eli: Is this ok for emacs-29? I'd love to add some test for this, but
> now they are on the master branch. What is the common procedure to move
> stuff from master branch to the release branch? I _can_ just add some
> test to the master branch, but it would be nice to have them on emacs-29
> too :-)
The procedure is "git cherry-pick", but I don't think I understand
what exactly is the problem here and what is the solution suggested to
solve it. Also, why does it need to be on emacs-29. Can you help me
understand that?
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 9:20 ` Eli Zaretskii
@ 2023-02-05 9:28 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 10:15 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 9:28 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 61142, zjyzhaojiyang
Eli Zaretskii <eliz@gnu.org> writes:
>
> The procedure is "git cherry-pick", but I don't think I understand
> what exactly is the problem here and what is the solution suggested to
> solve it. Also, why does it need to be on emacs-29. Can you help me
> understand that?
>
No need to have the test files on emacs-29. I could just as well add a
test when emacs-29 is synced to master later. The test-files themselves
don't exist on emacs-29.
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 9:28 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 10:15 ` Eli Zaretskii
2023-02-05 10:25 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2023-02-05 10:15 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142, zjyzhaojiyang
> From: Theodor Thornhill <theo@thornhill.no>
> Cc: zjyzhaojiyang@hotmail.com, 61142@debbugs.gnu.org
> Date: Sun, 05 Feb 2023 10:28:29 +0100
>
> Eli Zaretskii <eliz@gnu.org> writes:
>
> >
> > The procedure is "git cherry-pick", but I don't think I understand
> > what exactly is the problem here and what is the solution suggested to
> > solve it. Also, why does it need to be on emacs-29. Can you help me
> > understand that?
> >
>
> No need to have the test files on emacs-29. I could just as well add a
> test when emacs-29 is synced to master later. The test-files themselves
> don't exist on emacs-29.
OK, but still: what exactly is the problem that your patch is trying
to fix? I didn't understand that from the original report.
And one comment to the patch:
> @@ -300,6 +302,20 @@ java-ts-mode
> (c-ts-common-comment-setup)
>
> ;; Indent.
> + (setq-local c-ts-common-indent-block-type-regexp
> + (rx (or "class_body"
> + "\\`array_initializer"
> + "annotation_type_body"
> + "interface_body"
> + "interface_constructor_body"
> + "enum_body"
> + "switch_block"
> + "record_declaration_body"
> + "block")))
> + (setq-local c-ts-common-indent-bracketless-type-regexp
> + (rx (or "if_statement" "do_statement"
> + "for_statement" "while_statement")))
> + (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
> (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
>
> ;; Electric
Why are we adding a c-ts-common-SOMETHING variable to java-ts-mode.el?
Shouldn't it be named java-ts-SOMETHING instead? Or am I missing
something?
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 10:15 ` Eli Zaretskii
@ 2023-02-05 10:25 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 10:59 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 10:25 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 61142, zjyzhaojiyang
On 5 February 2023 11:15:47 CET, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Theodor Thornhill <theo@thornhill.no>
>> Cc: zjyzhaojiyang@hotmail.com, 61142@debbugs.gnu.org
>> Date: Sun, 05 Feb 2023 10:28:29 +0100
>>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>> >
>> > The procedure is "git cherry-pick", but I don't think I understand
>> > what exactly is the problem here and what is the solution suggested to
>> > solve it. Also, why does it need to be on emacs-29. Can you help me
>> > understand that?
>> >
>>
>> No need to have the test files on emacs-29. I could just as well add a
>> test when emacs-29 is synced to master later. The test-files themselves
>> don't exist on emacs-29.
>
>OK, but still: what exactly is the problem that your patch is trying
>to fix? I didn't understand that from the original report.
>
Oh right!
There are some indentation issues where if you have
void foo(
String foo) {
// ...
}
Then the normal code will indent like
void foo(
String foo) {
//...
}
Because of the parent-bol anchor. When these paired brackets are nested (and some other cases) we have to find the grand-parent, but that caused some other issues with ie c-ts-mode where compound_statements can be nested _and_ siblings. Yuan made an effort to make this work in c-ts-mode due to the many bug reports. He then generalized it into c-ts-common, for use in other modes, like java.
This patch adds support for that in java.
>And one comment to the patch:
>
>> @@ -300,6 +302,20 @@ java-ts-mode
>> (c-ts-common-comment-setup)
>>
>> ;; Indent.
>> + (setq-local c-ts-common-indent-block-type-regexp
>> + (rx (or "class_body"
>> + "\\`array_initializer"
>> + "annotation_type_body"
>> + "interface_body"
>> + "interface_constructor_body"
>> + "enum_body"
>> + "switch_block"
>> + "record_declaration_body"
>> + "block")))
>> + (setq-local c-ts-common-indent-bracketless-type-regexp
>> + (rx (or "if_statement" "do_statement"
>> + "for_statement" "while_statement")))
>> + (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
>> (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
>>
>> ;; Electric
>
>Why are we adding a c-ts-common-SOMETHING variable to java-ts-mode.el?
>Shouldn't it be named java-ts-SOMETHING instead? Or am I missing
>something?
This is because there is some setup involved in the new bracket-counting code in c-ts-common.
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 10:25 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 10:59 ` Eli Zaretskii
0 siblings, 0 replies; 17+ messages in thread
From: Eli Zaretskii @ 2023-02-05 10:59 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142, zjyzhaojiyang
> Date: Sun, 05 Feb 2023 11:25:52 +0100
> From: Theodor Thornhill <theo@thornhill.no>
> CC: zjyzhaojiyang@hotmail.com, 61142@debbugs.gnu.org
>
> There are some indentation issues where if you have
>
> void foo(
> String foo) {
> // ...
> }
>
> Then the normal code will indent like
>
> void foo(
> String foo) {
> //...
> }
>
> Because of the parent-bol anchor. When these paired brackets are nested (and some other cases) we have to find the grand-parent, but that caused some other issues with ie c-ts-mode where compound_statements can be nested _and_ siblings. Yuan made an effort to make this work in c-ts-mode due to the many bug reports. He then generalized it into c-ts-common, for use in other modes, like java.
>
> This patch adds support for that in java.
>
>
> >And one comment to the patch:
> >
> >> @@ -300,6 +302,20 @@ java-ts-mode
> >> (c-ts-common-comment-setup)
> >>
> >> ;; Indent.
> >> + (setq-local c-ts-common-indent-block-type-regexp
> >> + (rx (or "class_body"
> >> + "\\`array_initializer"
> >> + "annotation_type_body"
> >> + "interface_body"
> >> + "interface_constructor_body"
> >> + "enum_body"
> >> + "switch_block"
> >> + "record_declaration_body"
> >> + "block")))
> >> + (setq-local c-ts-common-indent-bracketless-type-regexp
> >> + (rx (or "if_statement" "do_statement"
> >> + "for_statement" "while_statement")))
> >> + (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
> >> (setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
> >>
> >> ;; Electric
> >
> >Why are we adding a c-ts-common-SOMETHING variable to java-ts-mode.el?
> >Shouldn't it be named java-ts-SOMETHING instead? Or am I missing
> >something?
>
> This is because there is some setup involved in the new bracket-counting code in c-ts-common.
OK, please install on emacs-29, and thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:54 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 9:20 ` Eli Zaretskii
@ 2023-02-05 13:09 ` 赵 纪阳
2023-02-05 19:19 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2 siblings, 1 reply; 17+ messages in thread
From: 赵 纪阳 @ 2023-02-05 13:09 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142@debbugs.gnu.org
[-- Attachment #1: Type: text/plain, Size: 2272 bytes --]
Thanks for the patch.
I've not tested this patch adequately, but I found an issue:
java-ts-mode indents the body of `else if` with one more level of indentation.
```
public class T {
int f() {
int a = 0;
int b = 1;
if (a == 0
&& b == 1) {
// indentation ok
return 0;
} else if (a == 1 ) {
// indentation more
return 1;
}
}
}
```
If the second branch of the if-statement is just an `else` (not `else if`), the body of it will be indented correctly.
I've also tested c-ts-mode (use 'linux as c-ts-mode-indent-style) and it also has this kind of problem.
```
int main() {
int a = 0;
if (a == 0) {
// indentation ok
} else if (a == 2) {
// indentation more
}
}
```
________________________________
发件人: Theodor Thornhill <theo@thornhill.no>
发送时间: 2023年2月5日 15:53
收件人: 太阳 <zjyzhaojiyang@hotmail.com>
抄送: 61142@debbugs.gnu.org <61142@debbugs.gnu.org>
主题: Re: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
Theodor Thornhill <theo@thornhill.no> writes:
> 太阳 <zjyzhaojiyang@hotmail.com> writes:
>
>> After reading treesit's manual, I found that we can use `n-p-gp` as the matcher
>> and `grand-parent` as the anchor to match the body of `if` (and `while`, which
>> has a similar issue).
>>
>> I mean a rule looks like the following:
>>
>> ```
>> ((n-p-gp nil "block" "if_statement") grand-parent java-ts-mode-indent-offset)
>> ```
>>
>>
>
>
> Thanks! We have a mechanism in place for this, see
> 'c-ts-common-statement-offset' in 'c-ts-common.el'. I didn't get to it
> yet, but I'll try to look at it this evening, unless you want to? See
> c-ts-mode for examples of how to use it, if you're interested!
>
> Theo
Hi again!
Can you test this patch for me?
@Eli: Is this ok for emacs-29? I'd love to add some test for this, but
now they are on the master branch. What is the common procedure to move
stuff from master branch to the release branch? I _can_ just add some
test to the master branch, but it would be nice to have them on emacs-29
too :-)
Theo
[-- Attachment #2: Type: text/html, Size: 6518 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 13:09 ` bug#61142: 回复: " 赵 纪阳
@ 2023-02-05 19:19 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 19:30 ` Eli Zaretskii
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 19:19 UTC (permalink / raw)
To: 赵 纪阳; +Cc: 61142@debbugs.gnu.org
[-- Attachment #1: Type: text/plain, Size: 1180 bytes --]
赵 纪阳 <zjyzhaojiyang@hotmail.com> writes:
> Thanks for the patch.
>
Thanks for testing!
> I've not tested this patch adequately, but I found an issue:
> java-ts-mode indents the body of `else if` with one more level of indentation.
>
> ```
> public class T {
> int f() {
> int a = 0;
> int b = 1;
> if (a == 0
> && b == 1) {
> // indentation ok
> return 0;
> } else if (a == 1 ) {
> // indentation more
> return 1;
> }
> }
> }
> ```
> If the second branch of the if-statement is just an `else` (not `else if`), the body of it will be indented correctly.
>
>
> I've also tested c-ts-mode (use 'linux as c-ts-mode-indent-style) and it also has this kind of problem.
> ```
> int main() {
> int a = 0;
> if (a == 0) {
> // indentation ok
> } else if (a == 2) {
> // indentation more
> }
> }
> ```
>
Right, I remember this. This finally made me create a fix - can you
test the provided patch and check if this works for you? It works
nicely for me, at least.
Theo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-c-ts-common-statement-offset-in-java-ts-mode.patch --]
[-- Type: text/x-patch, Size: 6547 bytes --]
From 95c381d40cf6907e333acb107160d901740da79d Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <theo@thornhill.no>
Date: Sun, 5 Feb 2023 08:49:08 +0100
Subject: [PATCH] Use c-ts-common-statement-offset in java-ts-mode
* lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): Add new
matchers to enable c-ts-common machinery.
(java-ts-mode): Add regexps.
* lisp/progmodes/c-ts-common.el (c-ts-common-statement-offset): Fix
typo in documentation and use the new if statement helpers.
(c-ts-common-if-statement-regexp): New defvar.
(c-ts-common-nestable-if-statement-p): New defvar.
(c-ts-common--fix-nestable-if-statement): New helper.
---
lisp/progmodes/c-ts-common.el | 26 +++++++++++++++++++++++-
lisp/progmodes/java-ts-mode.el | 36 +++++++++++++++++++++++++---------
2 files changed, 52 insertions(+), 10 deletions(-)
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 8729cae4ba..2edb979be5 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -281,11 +281,32 @@ c-ts-common-indent-bracketless-type-regexp
This can be nil, meaning such special handling is not needed.")
+(defvar c-ts-common-if-statement-regexp "if_statement"
+ "Regexp used to select an if statement in a C like language.
+
+This can be set to a different regexp if needed.")
+
+(defvar c-ts-common-nestable-if-statement-p t
+ "Does the current parser nest if-else statements?
+
+T if the current tree-sitter grammar nests the else if
+statements, NIL otherwise.")
+
+(defun c-ts-common--fix-nestable-if-statement (level node)
+ (or (and node
+ (treesit-node-parent node)
+ c-ts-common-nestable-if-statement-p
+ (equal (treesit-node-type node) c-ts-common-if-statement-regexp)
+ (equal (treesit-node-type (treesit-node-parent node))
+ c-ts-common-if-statement-regexp)
+ (cl-decf level))
+ level))
+
(defun c-ts-common-statement-offset (node parent bol &rest _)
"This anchor is used for children of a statement inside a block.
This function basically counts the number of block nodes (i.e.,
-brackets) (defined by `c-ts-mode--indent-block-type-regexp')
+brackets) (defined by `c-ts-common-indent-block-type-regexp')
between NODE and the root node (not counting NODE itself), and
multiply that by `c-ts-common-indent-offset'.
@@ -312,6 +333,9 @@ c-ts-common-statement-offset
(while (if (eq node t)
(setq node parent)
node)
+ ;; Subtract one indent level if the language nests
+ ;; if-statements and node is if_statement.
+ (setq level (c-ts-common--fix-nestable-if-statement level node))
(when (string-match-p c-ts-common-indent-block-type-regexp
(treesit-node-type node))
(cl-incf level)
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index b9f7894095..b3ecbd5987 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -70,22 +70,24 @@ java-ts-mode--syntax-table
(defvar java-ts-mode--indent-rules
`((java
((parent-is "program") point-min 0)
- ((node-is "}") (and parent parent-bol) 0)
+ ((match "}" "element_value_array_initializer")
+ parent-bol 0)
+ ((node-is "}") point-min c-ts-common-statement-offset)
((node-is ")") parent-bol 0)
((node-is "]") parent-bol 0)
((and (parent-is "comment") c-ts-common-looking-at-star)
c-ts-common-comment-start-after-first-star -1)
((parent-is "comment") prev-adaptive-prefix 0)
((parent-is "text_block") no-indent)
- ((parent-is "class_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "class_body") point-min c-ts-common-statement-offset)
((parent-is "array_initializer") parent-bol java-ts-mode-indent-offset)
- ((parent-is "annotation_type_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "interface_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "constructor_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "annotation_type_body") point-min c-ts-common-statement-offset)
+ ((parent-is "interface_body") point-min c-ts-common-statement-offset)
+ ((parent-is "constructor_body") point-min c-ts-common-statement-offset)
((parent-is "enum_body_declarations") parent-bol 0)
- ((parent-is "enum_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "switch_block") parent-bol java-ts-mode-indent-offset)
- ((parent-is "record_declaration_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "enum_body") point-min c-ts-common-statement-offset)
+ ((parent-is "switch_block") point-min c-ts-common-statement-offset)
+ ((parent-is "record_declaration_body") point-min c-ts-common-statement-offset)
((query "(method_declaration (block _ @indent))") parent-bol java-ts-mode-indent-offset)
((query "(method_declaration (block (_) @indent))") parent-bol java-ts-mode-indent-offset)
((parent-is "local_variable_declaration") parent-bol java-ts-mode-indent-offset)
@@ -118,7 +120,7 @@ java-ts-mode--indent-rules
((parent-is "case_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "labeled_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "do_statement") parent-bol java-ts-mode-indent-offset)
- ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)))
+ ((parent-is "block") point-min c-ts-common-statement-offset)))
"Tree-sitter indent rules.")
(defvar java-ts-mode--keywords
@@ -300,6 +302,22 @@ java-ts-mode
(c-ts-common-comment-setup)
;; Indent.
+ (setq-local c-ts-common-indent-block-type-regexp
+ (regexp-opt '("class_body"
+ "array_initializer"
+ "annotation_type_body"
+ "interface_body"
+ "interface_constructor_body"
+ "enum_body"
+ "switch_block"
+ "record_declaration_body"
+ "block")))
+ (setq-local c-ts-common-indent-bracketless-type-regexp
+ (regexp-opt '("if_statement"
+ "do_statement"
+ "for_statement"
+ "while_statement")))
+ (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
(setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
;; Electric
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 19:19 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 19:30 ` Eli Zaretskii
2023-02-05 19:32 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: Eli Zaretskii @ 2023-02-05 19:30 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142, zjyzhaojiyang
> Cc: "61142@debbugs.gnu.org" <61142@debbugs.gnu.org>
> Date: Sun, 05 Feb 2023 20:19:19 +0100
> From: Theodor Thornhill via "Bug reports for GNU Emacs,
> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>
> +(defvar c-ts-common-nestable-if-statement-p t
> + "Does the current parser nest if-else statements?
> +
> +T if the current tree-sitter grammar nests the else if
> +statements, NIL otherwise.")
A nit: we use t and nil, lowercase, to refer to these two symbols.
Thanks.
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 19:30 ` Eli Zaretskii
@ 2023-02-05 19:32 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 20:12 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 19:32 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 61142, zjyzhaojiyang
Eli Zaretskii <eliz@gnu.org> writes:
>> Cc: "61142@debbugs.gnu.org" <61142@debbugs.gnu.org>
>> Date: Sun, 05 Feb 2023 20:19:19 +0100
>> From: Theodor Thornhill via "Bug reports for GNU Emacs,
>> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>
>> +(defvar c-ts-common-nestable-if-statement-p t
>> + "Does the current parser nest if-else statements?
>> +
>> +T if the current tree-sitter grammar nests the else if
>> +statements, NIL otherwise.")
>
> A nit: we use t and nil, lowercase, to refer to these two symbols.
>
> Thanks.
Thanks!
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 19:32 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 20:12 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 21:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 20:12 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 61142, zjyzhaojiyang
[-- Attachment #1: Type: text/plain, Size: 1776 bytes --]
Theodor Thornhill <theo@thornhill.no> writes:
> Eli Zaretskii <eliz@gnu.org> writes:
>
>>> Cc: "61142@debbugs.gnu.org" <61142@debbugs.gnu.org>
>>> Date: Sun, 05 Feb 2023 20:19:19 +0100
>>> From: Theodor Thornhill via "Bug reports for GNU Emacs,
>>> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>>
>>> +(defvar c-ts-common-nestable-if-statement-p t
>>> + "Does the current parser nest if-else statements?
>>> +
>>> +T if the current tree-sitter grammar nests the else if
>>> +statements, NIL otherwise.")
>>
>> A nit: we use t and nil, lowercase, to refer to these two symbols.
>>
>> Thanks.
>
> Thanks!
>
> Theo
I added some small tweaks, and will add the following as a test later:
```
public class Java {
public Java(
String foo) {
this.foo = foo;
}
void foo(
String foo) {
for (var f : rs)
return new String[]{
"foo",
"bar"
};
if (a == 0
&& b == 1
&& foo) {
return 0;
} else if (a == 1) {
return 1;
} else if (true)
return 5;
else {
if (a == 0
&& b == 1
&& foo)
while (true)
for (
;;)
if (true)
return 5;
else if (false) {
return 6;
} else
if (true
&& false)
return 6;
}
}
}
```
Even though its some pretty wild code, its indented correctly after this
patch. I'll create something similar for C as well.
Theo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-c-ts-common-statement-offset-in-java-ts-mode-bug.patch --]
[-- Type: text/x-patch, Size: 7126 bytes --]
From e2e931843936134f157ee6259167b6aae429da3a Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <theo@thornhill.no>
Date: Sun, 5 Feb 2023 08:49:08 +0100
Subject: [PATCH] Use c-ts-common-statement-offset in java-ts-mode (bug#61142)
* lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): Add new
matchers to enable c-ts-common machinery.
(java-ts-mode): Add regexps.
* lisp/progmodes/c-ts-common.el (c-ts-common-statement-offset): Fix
typo in documentation and use the new if statement helpers.
(c-ts-common-if-statement-regexp): New defvar.
(c-ts-common-nestable-if-statement-p): New defvar.
(c-ts-common--fix-nestable-if-statement): New helper.
---
lisp/progmodes/c-ts-common.el | 33 ++++++++++++++++++++++++++++++-
lisp/progmodes/java-ts-mode.el | 36 +++++++++++++++++++++++++---------
2 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 8729cae4ba..affb38139a 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -281,11 +281,22 @@ c-ts-common-indent-bracketless-type-regexp
This can be nil, meaning such special handling is not needed.")
+(defvar c-ts-common-if-statement-regexp "if_statement"
+ "Regexp used to select an if statement in a C like language.
+
+This can be set to a different regexp if needed.")
+
+(defvar c-ts-common-nestable-if-statement-p t
+ "Does the current parser nest if-else statements?
+
+t if the current tree-sitter grammar nests the else if
+statements, nil otherwise.")
+
(defun c-ts-common-statement-offset (node parent bol &rest _)
"This anchor is used for children of a statement inside a block.
This function basically counts the number of block nodes (i.e.,
-brackets) (defined by `c-ts-mode--indent-block-type-regexp')
+brackets) (defined by `c-ts-common-indent-block-type-regexp')
between NODE and the root node (not counting NODE itself), and
multiply that by `c-ts-common-indent-offset'.
@@ -312,6 +323,9 @@ c-ts-common-statement-offset
(while (if (eq node t)
(setq node parent)
node)
+ ;; Subtract one indent level if the language nests
+ ;; if-statements and node is if_statement.
+ (setq level (c-ts-common--fix-nestable-if-statement level node))
(when (string-match-p c-ts-common-indent-block-type-regexp
(treesit-node-type node))
(cl-incf level)
@@ -354,6 +368,23 @@ c-ts-mode--fix-bracketless-indent
(1+ level)
level)))
+(defun c-ts-common--fix-nestable-if-statement (level node)
+ "Takes LEVEL and NODE and return adjusted LEVEL.
+Look at the type of NODE, when it is an if-statement node, as
+defined by `c-ts-common-if-statement-regexp' and its parent is
+also an if-statement node, subtract one level. Otherwise return
+the value unchanged. Whether or not if-statements are nestable
+is controlled by `c-ts-common-nestable-if-statement-p'."
+ ;; This fixes indentation for cases shown in bug#61142.
+ (or (and node
+ (treesit-node-parent node)
+ c-ts-common-nestable-if-statement-p
+ (equal (treesit-node-type node) c-ts-common-if-statement-regexp)
+ (equal (treesit-node-type (treesit-node-parent node))
+ c-ts-common-if-statement-regexp)
+ (cl-decf level))
+ level))
+
(provide 'c-ts-common)
;;; c-ts-common.el ends here
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index b9f7894095..1d7bdb0722 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -70,22 +70,25 @@ java-ts-mode--syntax-table
(defvar java-ts-mode--indent-rules
`((java
((parent-is "program") point-min 0)
- ((node-is "}") (and parent parent-bol) 0)
+ ((match "}" "element_value_array_initializer")
+ parent-bol 0)
+ ((node-is "}") point-min c-ts-common-statement-offset)
((node-is ")") parent-bol 0)
+ ((node-is "else") parent-bol 0)
((node-is "]") parent-bol 0)
((and (parent-is "comment") c-ts-common-looking-at-star)
c-ts-common-comment-start-after-first-star -1)
((parent-is "comment") prev-adaptive-prefix 0)
((parent-is "text_block") no-indent)
- ((parent-is "class_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "class_body") point-min c-ts-common-statement-offset)
((parent-is "array_initializer") parent-bol java-ts-mode-indent-offset)
- ((parent-is "annotation_type_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "interface_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "constructor_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "annotation_type_body") point-min c-ts-common-statement-offset)
+ ((parent-is "interface_body") point-min c-ts-common-statement-offset)
+ ((parent-is "constructor_body") point-min c-ts-common-statement-offset)
((parent-is "enum_body_declarations") parent-bol 0)
- ((parent-is "enum_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "switch_block") parent-bol java-ts-mode-indent-offset)
- ((parent-is "record_declaration_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "enum_body") point-min c-ts-common-statement-offset)
+ ((parent-is "switch_block") point-min c-ts-common-statement-offset)
+ ((parent-is "record_declaration_body") point-min c-ts-common-statement-offset)
((query "(method_declaration (block _ @indent))") parent-bol java-ts-mode-indent-offset)
((query "(method_declaration (block (_) @indent))") parent-bol java-ts-mode-indent-offset)
((parent-is "local_variable_declaration") parent-bol java-ts-mode-indent-offset)
@@ -118,7 +121,7 @@ java-ts-mode--indent-rules
((parent-is "case_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "labeled_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "do_statement") parent-bol java-ts-mode-indent-offset)
- ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)))
+ ((parent-is "block") point-min c-ts-common-statement-offset)))
"Tree-sitter indent rules.")
(defvar java-ts-mode--keywords
@@ -300,6 +303,21 @@ java-ts-mode
(c-ts-common-comment-setup)
;; Indent.
+ (setq-local c-ts-common-indent-block-type-regexp
+ (regexp-opt '("class_body"
+ "array_initializer"
+ "constructor_body"
+ "annotation_type_body"
+ "interface_body"
+ "enum_body"
+ "switch_block"
+ "record_declaration_body"
+ "block")))
+ (setq-local c-ts-common-indent-bracketless-type-regexp
+ (regexp-opt '("if_statement"
+ "for_statement"
+ "while_statement")))
+ (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
(setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
;; Electric
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 20:12 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-05 21:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-06 2:34 ` bug#61142: 回复: " 赵 纪阳
0 siblings, 1 reply; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-05 21:20 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 61142, zjyzhaojiyang
[-- Attachment #1: Type: text/plain, Size: 1226 bytes --]
Theodor Thornhill <theo@thornhill.no> writes:
> Theodor Thornhill <theo@thornhill.no> writes:
>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>>>> Cc: "61142@debbugs.gnu.org" <61142@debbugs.gnu.org>
>>>> Date: Sun, 05 Feb 2023 20:19:19 +0100
>>>> From: Theodor Thornhill via "Bug reports for GNU Emacs,
>>>> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>>>
>>>> +(defvar c-ts-common-nestable-if-statement-p t
>>>> + "Does the current parser nest if-else statements?
>>>> +
>>>> +T if the current tree-sitter grammar nests the else if
>>>> +statements, NIL otherwise.")
>>>
>>> A nit: we use t and nil, lowercase, to refer to these two symbols.
>>>
>>> Thanks.
>>
>> Thanks!
>>
>> Theo
>
> I added some small tweaks, and will add the following as a test later:
>
I made even further tweaks, and while testing the c variant I noticed
that the C tests weren't actually working. There were missing rules for
many of the cases in the tests, so I added some more rules to the
c-ts-mode indentation and added a big-ish test with some wonky but
seemingly working indentation.
Because the tests are now working I think this is good to go, so unless
somebody objects I'll install this sometime tomorrow :-)
Theo
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-c-ts-common-statement-offset-in-java-ts-mode-bug.patch --]
[-- Type: text/x-patch, Size: 9595 bytes --]
From 23d859a6bedab436b87db2458f15a69403bbef99 Mon Sep 17 00:00:00 2001
From: Theodor Thornhill <theo@thornhill.no>
Date: Sun, 5 Feb 2023 08:49:08 +0100
Subject: [PATCH] Use c-ts-common-statement-offset in java-ts-mode (bug#61142)
* lisp/progmodes/java-ts-mode.el (java-ts-mode--indent-rules): Add new
matchers to enable c-ts-common machinery.
(java-ts-mode): Add regexps.
* lisp/progmodes/c-ts-common.el (c-ts-common-statement-offset): Fix
typo in documentation and use the new if statement helpers.
(c-ts-common-if-statement-regexp): New defvar.
(c-ts-common-nestable-if-statement-p): New defvar.
(c-ts-common--fix-nestable-if-statement): New helper.
* test/lisp/progmodes/c-ts-mode-resources/indent.erts: Add test for
complicated bracket matching indentation.
* lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Add indent
rules for bracketless statements.
---
lisp/progmodes/c-ts-common.el | 34 +++++++++++++-
lisp/progmodes/c-ts-mode.el | 7 +++
lisp/progmodes/java-ts-mode.el | 36 +++++++++++----
.../progmodes/c-ts-mode-resources/indent.erts | 45 +++++++++++++++++++
4 files changed, 112 insertions(+), 10 deletions(-)
diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 8729cae4ba..6767f10a9e 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -281,11 +281,22 @@ c-ts-common-indent-bracketless-type-regexp
This can be nil, meaning such special handling is not needed.")
+(defvar c-ts-common-if-statement-regexp "if_statement"
+ "Regexp used to select an if statement in a C like language.
+
+This can be set to a different regexp if needed.")
+
+(defvar c-ts-common-nestable-if-statement-p t
+ "Does the current parser nest if-else statements?
+
+t if the current tree-sitter grammar nests the else if
+statements, nil otherwise.")
+
(defun c-ts-common-statement-offset (node parent bol &rest _)
"This anchor is used for children of a statement inside a block.
This function basically counts the number of block nodes (i.e.,
-brackets) (defined by `c-ts-mode--indent-block-type-regexp')
+brackets) (defined by `c-ts-common-indent-block-type-regexp')
between NODE and the root node (not counting NODE itself), and
multiply that by `c-ts-common-indent-offset'.
@@ -312,6 +323,9 @@ c-ts-common-statement-offset
(while (if (eq node t)
(setq node parent)
node)
+ ;; Subtract one indent level if the language nests
+ ;; if-statements and node is if_statement.
+ (setq level (c-ts-common--fix-nestable-if-statement level node))
(when (string-match-p c-ts-common-indent-block-type-regexp
(treesit-node-type node))
(cl-incf level)
@@ -354,6 +368,24 @@ c-ts-mode--fix-bracketless-indent
(1+ level)
level)))
+(defun c-ts-common--fix-nestable-if-statement (level node)
+ "Takes LEVEL and NODE and return adjusted LEVEL.
+Look at the type of NODE, when it is an if-statement node, as
+defined by `c-ts-common-if-statement-regexp' and its parent is
+also an if-statement node, subtract one level. Otherwise return
+the value unchanged. Whether or not if-statements are nestable
+is controlled by `c-ts-common-nestable-if-statement-p'."
+ ;; This fixes indentation for cases shown in bug#61142.
+ (or (and node
+ (equal (treesit-node-type (treesit-node-prev-sibling node)) "else")
+ (treesit-node-parent node)
+ c-ts-common-nestable-if-statement-p
+ (equal (treesit-node-type node) c-ts-common-if-statement-regexp)
+ (equal (treesit-node-type (treesit-node-parent node))
+ c-ts-common-if-statement-regexp)
+ (cl-decf level))
+ level))
+
(provide 'c-ts-common)
;;; c-ts-common.el ends here
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 5093c3980b..e3d8c9ddad 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -238,6 +238,13 @@ c-ts-mode--indent-styles
((parent-is "labeled_statement")
point-min c-ts-common-statement-offset)
+ ;; Bracketless statement matchers.
+ ((match nil "while_statement" "condition") parent-bol c-ts-mode-indent-offset)
+ ((match nil "if_statement" "consequence") parent-bol c-ts-mode-indent-offset)
+ ((match nil "if_statement" "alternative") parent-bol c-ts-mode-indent-offset)
+ ((match nil "do_statement" "body") parent-bol c-ts-mode-indent-offset)
+ ((match nil "for_statement" "body") parent-bol c-ts-mode-indent-offset)
+
((match "preproc_ifdef" "compound_statement") point-min 0)
((match "#endif" "preproc_ifdef") point-min 0)
((match "preproc_if" "compound_statement") point-min 0)
diff --git a/lisp/progmodes/java-ts-mode.el b/lisp/progmodes/java-ts-mode.el
index b9f7894095..1d7bdb0722 100644
--- a/lisp/progmodes/java-ts-mode.el
+++ b/lisp/progmodes/java-ts-mode.el
@@ -70,22 +70,25 @@ java-ts-mode--syntax-table
(defvar java-ts-mode--indent-rules
`((java
((parent-is "program") point-min 0)
- ((node-is "}") (and parent parent-bol) 0)
+ ((match "}" "element_value_array_initializer")
+ parent-bol 0)
+ ((node-is "}") point-min c-ts-common-statement-offset)
((node-is ")") parent-bol 0)
+ ((node-is "else") parent-bol 0)
((node-is "]") parent-bol 0)
((and (parent-is "comment") c-ts-common-looking-at-star)
c-ts-common-comment-start-after-first-star -1)
((parent-is "comment") prev-adaptive-prefix 0)
((parent-is "text_block") no-indent)
- ((parent-is "class_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "class_body") point-min c-ts-common-statement-offset)
((parent-is "array_initializer") parent-bol java-ts-mode-indent-offset)
- ((parent-is "annotation_type_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "interface_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "constructor_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "annotation_type_body") point-min c-ts-common-statement-offset)
+ ((parent-is "interface_body") point-min c-ts-common-statement-offset)
+ ((parent-is "constructor_body") point-min c-ts-common-statement-offset)
((parent-is "enum_body_declarations") parent-bol 0)
- ((parent-is "enum_body") parent-bol java-ts-mode-indent-offset)
- ((parent-is "switch_block") parent-bol java-ts-mode-indent-offset)
- ((parent-is "record_declaration_body") parent-bol java-ts-mode-indent-offset)
+ ((parent-is "enum_body") point-min c-ts-common-statement-offset)
+ ((parent-is "switch_block") point-min c-ts-common-statement-offset)
+ ((parent-is "record_declaration_body") point-min c-ts-common-statement-offset)
((query "(method_declaration (block _ @indent))") parent-bol java-ts-mode-indent-offset)
((query "(method_declaration (block (_) @indent))") parent-bol java-ts-mode-indent-offset)
((parent-is "local_variable_declaration") parent-bol java-ts-mode-indent-offset)
@@ -118,7 +121,7 @@ java-ts-mode--indent-rules
((parent-is "case_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "labeled_statement") parent-bol java-ts-mode-indent-offset)
((parent-is "do_statement") parent-bol java-ts-mode-indent-offset)
- ((parent-is "block") (and parent parent-bol) java-ts-mode-indent-offset)))
+ ((parent-is "block") point-min c-ts-common-statement-offset)))
"Tree-sitter indent rules.")
(defvar java-ts-mode--keywords
@@ -300,6 +303,21 @@ java-ts-mode
(c-ts-common-comment-setup)
;; Indent.
+ (setq-local c-ts-common-indent-block-type-regexp
+ (regexp-opt '("class_body"
+ "array_initializer"
+ "constructor_body"
+ "annotation_type_body"
+ "interface_body"
+ "enum_body"
+ "switch_block"
+ "record_declaration_body"
+ "block")))
+ (setq-local c-ts-common-indent-bracketless-type-regexp
+ (regexp-opt '("if_statement"
+ "for_statement"
+ "while_statement")))
+ (setq-local c-ts-common-indent-offset 'java-ts-mode-indent-offset)
(setq-local treesit-simple-indent-rules java-ts-mode--indent-rules)
;; Electric
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent.erts b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
index 7dcc3b0fb3..6f64e1e795 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
@@ -244,3 +244,48 @@ int main() {
}
}
=-=-=
+
+Name: Complicated mixed bracket matching indentation (bug#61142)
+
+=-=
+void foo(
+ int foo) {
+ for (;;)
+ return 5;
+
+ if (a == 0
+ && b == 1
+ && foo)
+ {
+ return 0;
+ }
+ else if (a == 1)
+ {
+ return 1;
+ }
+ else if (true)
+ return 5;
+ else
+ {
+ if (a == 0
+ && b == 1
+ && foo)
+ for (
+ int i = 0;
+ i < 5;
+ i++)
+ if (true)
+ do
+ i = 5;
+ while (true);
+ else if (false)
+ {
+ return 6;
+ }
+ else
+ if (true
+ && false)
+ return 6;
+ }
+}
+=-=-=
--
2.34.1
^ permalink raw reply related [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-05 21:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
@ 2023-02-06 2:34 ` 赵 纪阳
2023-02-06 6:45 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 1 reply; 17+ messages in thread
From: 赵 纪阳 @ 2023-02-06 2:34 UTC (permalink / raw)
To: Theodor Thornhill; +Cc: 61142@debbugs.gnu.org
[-- Attachment #1: Type: text/plain, Size: 1704 bytes --]
Hi Theo
This patch works well for me. Great! Thanks!
________________________________
发件人: Theodor Thornhill <theo@thornhill.no>
发送时间: 2023年2月6日 5:20
收件人: Eli Zaretskii <eliz@gnu.org>
抄送: zjyzhaojiyang@hotmail.com <zjyzhaojiyang@hotmail.com>; 61142@debbugs.gnu.org <61142@debbugs.gnu.org>
主题: Re: bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
Theodor Thornhill <theo@thornhill.no> writes:
> Theodor Thornhill <theo@thornhill.no> writes:
>
>> Eli Zaretskii <eliz@gnu.org> writes:
>>
>>>> Cc: "61142@debbugs.gnu.org" <61142@debbugs.gnu.org>
>>>> Date: Sun, 05 Feb 2023 20:19:19 +0100
>>>> From: Theodor Thornhill via "Bug reports for GNU Emacs,
>>>> the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
>>>>
>>>> +(defvar c-ts-common-nestable-if-statement-p t
>>>> + "Does the current parser nest if-else statements?
>>>> +
>>>> +T if the current tree-sitter grammar nests the else if
>>>> +statements, NIL otherwise.")
>>>
>>> A nit: we use t and nil, lowercase, to refer to these two symbols.
>>>
>>> Thanks.
>>
>> Thanks!
>>
>> Theo
>
> I added some small tweaks, and will add the following as a test later:
>
I made even further tweaks, and while testing the c variant I noticed
that the C tests weren't actually working. There were missing rules for
many of the cases in the tests, so I added some more rules to the
c-ts-mode indentation and added a big-ish test with some wonky but
seemingly working indentation.
Because the tests are now working I think this is good to go, so unless
somebody objects I'll install this sometime tomorrow :-)
Theo
[-- Attachment #2: Type: text/html, Size: 3246 bytes --]
^ permalink raw reply [flat|nested] 17+ messages in thread
* bug#61142: 回复: bug#61142: 回复: bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions
2023-02-06 2:34 ` bug#61142: 回复: " 赵 纪阳
@ 2023-02-06 6:45 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
0 siblings, 0 replies; 17+ messages in thread
From: Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors @ 2023-02-06 6:45 UTC (permalink / raw)
To: 赵 纪阳; +Cc: 61142@debbugs.gnu.org
赵 纪阳 <zjyzhaojiyang@hotmail.com> writes:
> Hi Theo
>
> This patch works well for me. Great! Thanks!
>
Great news - thanks for the feedback - now pushed :-)
Theo
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2023-02-06 6:45 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <handler.61142.B.16749811447164.ack@debbugs.gnu.org>
2023-02-01 8:46 ` bug#61142: Acknowledgement (29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions) 太阳
2023-02-04 10:45 ` bug#61142: 29.0.60; java-ts-mode - Wrong indentation for the body of multiple lines conditions Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:53 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 7:54 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 9:20 ` Eli Zaretskii
2023-02-05 9:28 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 10:15 ` Eli Zaretskii
2023-02-05 10:25 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 10:59 ` Eli Zaretskii
2023-02-05 13:09 ` bug#61142: 回复: " 赵 纪阳
2023-02-05 19:19 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 19:30 ` Eli Zaretskii
2023-02-05 19:32 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 20:12 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-05 21:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2023-02-06 2:34 ` bug#61142: 回复: " 赵 纪阳
2023-02-06 6:45 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).