emacs-diffs
[Top][All Lists]
Advanced

[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)
 
 =-=



reply via email to

[Prev in Thread] Current Thread [Next in Thread]