[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
emacs-29 cdf74254ff 3/3: Fix indentation for c-ts-mode (bug#61026)
From: |
Yuan Fu |
Subject: |
emacs-29 cdf74254ff 3/3: Fix indentation for c-ts-mode (bug#61026) |
Date: |
Thu, 26 Jan 2023 02:52:10 -0500 (EST) |
branch: emacs-29
commit cdf74254ffa2c53612f6d985e3774b51233fbd49
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>
Fix indentation for c-ts-mode (bug#61026)
Fix indentation for things like
while (true)
if (true)
{
puts ("Hello");
}
Note that the outer while loop omits brackets.
* lisp/progmodes/c-ts-mode.el:
(c-ts-mode--statement-offset-post-processr): New variable.
(c-ts-mode--statement-offset): Use the new function.
(c-ts-mode--fix-bracketless-indent): New function.
(c-ts-base-mode): Use the new function.
* test/lisp/progmodes/c-ts-mode-resources/indent.erts: New tests.
---
lisp/progmodes/c-ts-mode.el | 32 ++++++++++++-
.../lisp/progmodes/c-ts-mode-resources/indent.erts | 52 ++++++++++++++++++++++
2 files changed, 83 insertions(+), 1 deletion(-)
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 95f9001e0d..788c911f86 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -279,6 +279,19 @@ NODE should be a labeled_statement."
"enumerator_list"))
"Regexp matching types of block nodes (i.e., {} blocks).")
+(defvar c-ts-mode--statement-offset-post-processr nil
+ "A functions that makes adjustments to `c-ts-mode--statement-offset'.
+
+This is a function that takes two arguments, the current indent
+level and the current node, and returns a new level.
+
+When `c-ts-mode--statement-offset' runs and go up the parse tree,
+it increments the indent level when some condition are met in
+each level. At each level, after (possibly) incrementing the
+offset, it calls this function, passing it the current indent
+level and the current node, and use the return value as the new
+indent level.")
+
(defun c-ts-mode--statement-offset (node parent &rest _)
"This anchor is used for children of a statement inside a block.
@@ -319,9 +332,24 @@ PARENT is NODE's parent."
;; Add a level.
((looking-back (rx bol (* whitespace))
(line-beginning-position))
- (cl-incf level))))))
+ (cl-incf level)))))
+ (when c-ts-mode--statement-offset-post-processr
+ (setq level (funcall c-ts-mode--statement-offset-post-processr
+ level node))))
(* level c-ts-mode-indent-offset)))
+(defun c-ts-mode--fix-bracketless-indent (level node)
+ "Takes LEVEL and NODE and returns adjusted LEVEL.
+This fixes indentation for cases shown in bug#61026. Basically
+in C/C++, constructs like if, for, while sometimes don't have
+bracket."
+ (if (and (not (equal (treesit-node-type node) "compound_statement"))
+ (member (treesit-node-type (treesit-node-parent node))
+ '("if_statement" "while_statement" "do_statement"
+ "for_statement")))
+ (1+ level)
+ level))
+
(defun c-ts-mode--close-bracket-offset (node parent &rest _)
"Offset for the closing bracket, NODE.
It's basically one level less that the statements in the block.
@@ -758,6 +786,8 @@ the semicolon. This function skips the semicolon."
;; Indent.
(when (eq c-ts-mode-indent-style 'linux)
(setq-local indent-tabs-mode t))
+ (setq-local c-ts-mode--statement-offset-post-processr
+ #'c-ts-mode--fix-bracketless-indent)
;; Comment
(c-ts-common-comment-setup)
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent.erts
b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
index b8524432d0..67654404a7 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
@@ -105,6 +105,58 @@ main (int argc,
}
=-=-=
+Name: Bracket-less Block-Statement (GNU Style) (bug#61026)
+
+=-=
+int main() {
+ while (true)
+ if (true)
+ {
+ puts ("Hello");
+ }
+ for (int i=0; i<5; i++)
+ if (true)
+ {
+ puts ("Hello");
+ }
+ do
+ if (true)
+ {
+ puts ("Hello");
+ }
+ while (true);
+ if (true)
+ if (true)
+ {
+ puts ("Hello");
+ }
+}
+=-=-=
+
+Name: Bracket-less Block-Statement (Linux Style) (bug#61026)
+
+=-=-=
+int main() {
+ while (true)
+ if (true) {
+ puts ("Hello");
+ }
+ for (int i=0; i<5; i++)
+ if (true) {
+ puts ("Hello");
+ }
+ do
+ if (true) {
+ puts ("Hello");
+ }
+ while (true);
+ if (true)
+ if (true) {
+ puts ("Hello");
+ }
+}
+=-=-=
+
Name: Multiline Parameter List (bug#60398)
=-=