From: Theodor Thornhill Date: Fri, 17 Feb 2023 19:46:19 +0000 (+0100) Subject: Cleanup preproc indent for c-ts-mode (bug#61558) X-Git-Tag: emacs-29.0.90~378 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=c544df4fa3f217d0039bb9cb38c809c830558c25;p=emacs.git Cleanup preproc indent for c-ts-mode (bug#61558) * 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. --- diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el index 05875e9267a..76c80d9a068 100644 --- a/lisp/progmodes/c-ts-mode.el +++ b/lisp/progmodes/c-ts-mode.el @@ -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 index 00000000000..5a4996f642e --- /dev/null +++ b/test/lisp/progmodes/c-ts-mode-resources/indent-preproc.erts @@ -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 +=-=-= diff --git a/test/lisp/progmodes/c-ts-mode-tests.el b/test/lisp/progmodes/c-ts-mode-tests.el index ddf64b40736..ea5fab4cbef 100644 --- a/test/lisp/progmodes/c-ts-mode-tests.el +++ b/test/lisp/progmodes/c-ts-mode-tests.el @@ -27,6 +27,10 @@ (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")))