emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 836044f329a: Fix c-ts-mode preproc directive indentation


From: Yuan Fu
Subject: emacs-29 836044f329a: Fix c-ts-mode preproc directive indentation
Date: Sat, 4 Mar 2023 18:03:39 -0500 (EST)

branch: emacs-29
commit 836044f329a0a96810f2d88471cb040b9d373cce
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    Fix c-ts-mode preproc directive indentation
    
    Mentioned in bug#61893, although not the subject of that report.  This
    change fixes indentation for nested directives.  For example, when the
    directive involves elif and the like, the elif is nested in the if
    directive, so simply using grand-parent and great-grand-parent for
    anchor is insufficient, because the nesting can grow arbitrarily.
    
    The test added also covers the last preproc fix.
    
    * lisp/progmodes/c-ts-mode.el:
    (c-ts-mode--standalone-parent-skip-preproc): New function.
    (c-ts-mode--indent-styles): New rules.
    * test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts: New test.
---
 lisp/progmodes/c-ts-mode.el                        | 36 ++++++++++++++++++++--
 .../c-ts-mode-resources/indent-preproc.erts        | 34 ++++++++++++++++++++
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 05c471e6fb4..f40bbc57eb5 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -299,6 +299,23 @@ PARENT and BOL are like other anchor functions."
     ;; prev-sibling doesn't have a child.
     (treesit-node-start prev-sibling)))
 
+(defun c-ts-mode--standalone-parent-skip-preproc (_n parent &rest _)
+  "Like the standalone-parent anchor but skips preproc nodes.
+PARENT is the same as other anchor functions."
+  (save-excursion
+    (treesit-node-start
+     (treesit-parent-until
+      ;; Use PARENT rather than NODE, to handle the case where NODE is
+      ;; nil.
+      parent (lambda (node)
+               (and node
+                    (not (string-match "preproc" (treesit-node-type node)))
+                    (progn
+                      (goto-char (treesit-node-start node))
+                      (looking-back (rx bol (* whitespace))
+                                    (line-beginning-position)))))
+      t))))
+
 (defun c-ts-mode--standalone-grandparent (_node parent bol &rest args)
   "Like the standalone-parent anchor but pass it the grandparent.
 PARENT, BOL, ARGS are the same as other anchor functions."
@@ -330,13 +347,28 @@ MODE is either `c' or `cpp'."
            ((parent-is "labeled_statement")
             c-ts-mode--standalone-grandparent c-ts-mode-indent-offset)
 
+           ;; Preproc directives
            ((node-is "preproc") column-0 0)
            ((node-is "#endif") column-0 0)
            ((match "preproc_call" "compound_statement") column-0 0)
 
+           ;; Top-level things under a preproc directive.  Note that
+           ;; "preproc" matches more than one type: it matches
+           ;; preproc_if, preproc_elif, etc.
            ((n-p-gp nil "preproc" "translation_unit") column-0 0)
-           ((n-p-gp nil "\n" "preproc") great-grand-parent 
c-ts-mode--preproc-offset)
-           ((parent-is "preproc") grand-parent c-ts-mode-indent-offset)
+           ;; Indent rule for an empty line after a preproc directive.
+           ((and no-node (parent-is ,(rx (or "\n" "preproc"))))
+            c-ts-mode--standalone-parent-skip-preproc 
c-ts-mode--preproc-offset)
+           ;; Statement under a preproc directive, the first statement
+           ;; indents against parent, the rest statements indent to
+           ;; their prev-sibling.
+           ((match nil ,(rx "preproc_" (or "if" "elif")) nil 3 3)
+            c-ts-mode--standalone-parent-skip-preproc c-ts-mode-indent-offset)
+           ((match nil "preproc_ifdef" nil 2 2)
+            c-ts-mode--standalone-parent-skip-preproc c-ts-mode-indent-offset)
+           ((match nil "preproc_else" nil 1 1)
+            c-ts-mode--standalone-parent-skip-preproc c-ts-mode-indent-offset)
+           ((parent-is "preproc") c-ts-mode--anchor-prev-sibling 0)
 
            ((parent-is "function_definition") parent-bol 0)
            ((parent-is "conditional_expression") first-sibling 0)
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts 
b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts
index 57610b5483e..0f9256ad984 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts
@@ -44,3 +44,37 @@ static void
 /* */
 static void
 =-=-=
+
+Code:
+  (lambda ()
+    (c-ts-mode)
+    (setq-local indent-tabs-mode nil)
+    (setq-local c-ts-mode-indent-offset 2)
+    (c-ts-mode-set-style 'gnu)
+    (indent-region (point-min) (point-max)))
+
+Name: Prev-Sibling When Prev-Sibling is Preproc
+
+=-=
+static void
+free_glyph_pool (struct glyph_pool *pool)
+{
+  if (pool)
+    {
+#if defined GLYPH_DEBUG
+      int c = 1;
+#endif
+      int check_this = 3;
+
+#ifdef stuff
+      int c = 1;
+#elif defined stuff
+      int e = 5;
+#else
+      int d = 11;
+      int f = 11;
+#endif
+      int check_this = 3;
+    }
+}
+=-=-=



reply via email to

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