[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
emacs-29 5a6dfab1e4 2/2: Use c-ts-common-statement-offset in java-ts-mod
From: |
Theodor Thornhill |
Subject: |
emacs-29 5a6dfab1e4 2/2: Use c-ts-common-statement-offset in java-ts-mode (bug#61142) |
Date: |
Mon, 6 Feb 2023 01:45:14 -0500 (EST) |
branch: emacs-29
commit 5a6dfab1e4d5d89e5d5ff3bef73279926f067dbc
Author: Theodor Thornhill <theo@thornhill.no>
Commit: Theodor Thornhill <theo@thornhill.no>
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 ++++++++++++-----
.../lisp/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 @@ special handling from our bracket-counting indent
algorithm.
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 @@ characters on the current line."
(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 @@ the bracket in the body."
(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 3740130be3..9381608166 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -238,6 +238,13 @@ MODE is either `c' or `cpp'."
((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 @@
(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 @@
((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 @@ Return nil if there is no name or if NODE is not a defun
node."
(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;
+ }
+}
+=-=-=