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.
This commit is contained in:
parent
64980a59b6
commit
836044f329
2 changed files with 68 additions and 2 deletions
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
=-=-=
|
||||
|
|
Loading…
Add table
Reference in a new issue