]> git.eshelyaron.com Git - emacs.git/commitdiff
Cleanup preproc indent for c-ts-mode (bug#61558)
authorTheodor Thornhill <theo@thornhill.no>
Fri, 17 Feb 2023 19:46:19 +0000 (20:46 +0100)
committerTheodor Thornhill <theo@thornhill.no>
Sun, 19 Feb 2023 19:47:05 +0000 (20:47 +0100)
* lisp/progmodes/c-ts-mode.el (c-ts-mode--indent-styles): Make sure we
indent to great-grand-parent if inside an #ifdef...#endif block.  If
grand-parent is root node, then don't indent one step.
(c-ts-mode--preproc-offset): New helper anchor function to calculate
indent offset.

lisp/progmodes/c-ts-mode.el
test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts [new file with mode: 0644]
test/lisp/progmodes/c-ts-mode-tests.el

index 05875e9267acfd269a14596f22c2eac63a7a53db..76c80d9a06819f3383cd9d49dae054a59e193559 100644 (file)
@@ -233,6 +233,25 @@ delimiters < and >'s."
 
 ;;; Indent
 
+(defun c-ts-mode--preproc-offset (_n _p &rest _)
+  "This anchor is used for preprocessor directives.
+
+Because node is nil at the moment of indentation, we use
+`treesit-node-on' to capture the anonymous node covering the
+newline.  If the grand-parent of that node is the
+translation_unit itself, we don't indent.  Otherwise, just indent
+one step according to the great-grand-parent indent level.  The
+reason there is a difference between grand-parent and
+great-grand-parent here is that the node containing the newline
+is actually the parent of point at the moment of indentation."
+  (when-let ((node (treesit-node-on (point) (point))))
+    (if (string-equal "translation_unit"
+                      (treesit-node-type
+                       (treesit-node-parent
+                        (treesit-node-parent node))))
+        0
+      c-ts-mode-indent-offset)))
+
 (defun c-ts-mode--indent-styles (mode)
   "Indent rules supported by `c-ts-mode'.
 MODE is either `c' or `cpp'."
@@ -265,13 +284,14 @@ MODE is either `c' or `cpp'."
            ((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)
-           ((match "#endif" "preproc_if") point-min 0)
-           ((match "preproc_function_def" "compound_statement") point-min 0)
+           ((node-is "preproc") point-min 0)
+           ((node-is "#endif") point-min 0)
            ((match "preproc_call" "compound_statement") point-min 0)
 
+           ((n-p-gp nil "preproc" "translation_unit") point-min 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)
+
            ((parent-is "function_definition") parent-bol 0)
            ((parent-is "conditional_expression") first-sibling 0)
            ((parent-is "assignment_expression") parent-bol c-ts-mode-indent-offset)
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts
new file mode 100644 (file)
index 0000000..5a4996f
--- /dev/null
@@ -0,0 +1,45 @@
+Code:
+  (lambda ()
+    (c-ts-mode)
+    (newline)
+    (indent-for-tab-command))
+
+Point-Char: |
+
+Name: Indents inside #if preproc
+
+=-=
+static void
+free_glyph_pool (struct glyph_pool *pool)
+{
+  if (pool)
+    {
+#if defined GLYPH_DEBUG|
+#endif
+    }
+}
+=-=
+static void
+free_glyph_pool (struct glyph_pool *pool)
+{
+  if (pool)
+    {
+#if defined GLYPH_DEBUG
+      |
+#endif
+    }
+}
+=-=-=
+
+Name: Indents to 0 if #if preproc at root
+
+=-=
+#if 0|
+/* */
+static void
+=-=
+#if 0
+|
+/* */
+static void
+=-=-=
index ddf64b407362c1b79b6873a35fd9c9620ecf0bdf..ea5fab4cbefa942240365d453d6aa0c16610ccc0 100644 (file)
   (skip-unless (treesit-ready-p 'c))
   (ert-test-erts-file (ert-resource-file "indent.erts")))
 
+(ert-deftest c-ts-mode-test-indentation-preproc ()
+  (skip-unless (treesit-ready-p 'c))
+  (ert-test-erts-file (ert-resource-file "indent-preproc.erts")))
+
 (ert-deftest c-ts-mode-test-indentation-bsd ()
   (skip-unless (treesit-ready-p 'c))
   (ert-test-erts-file (ert-resource-file "indent-bsd.erts")))