aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYuan Fu2023-01-25 23:47:27 -0800
committerYuan Fu2023-01-25 23:47:27 -0800
commitcdf74254ffa2c53612f6d985e3774b51233fbd49 (patch)
treed1bc32bc8f622bce15efa9335187b10411d4cfed
parent4bd06ce2a9fa1601aff5a5fcab7411e5fce20d28 (diff)
downloademacs-cdf74254ffa2c53612f6d985e3774b51233fbd49.tar.gz
emacs-cdf74254ffa2c53612f6d985e3774b51233fbd49.zip
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.
-rw-r--r--lisp/progmodes/c-ts-mode.el32
-rw-r--r--test/lisp/progmodes/c-ts-mode-resources/indent.erts52
2 files changed, 83 insertions, 1 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 95f9001e0d7..788c911f86b 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."
279 "enumerator_list")) 279 "enumerator_list"))
280 "Regexp matching types of block nodes (i.e., {} blocks).") 280 "Regexp matching types of block nodes (i.e., {} blocks).")
281 281
282(defvar c-ts-mode--statement-offset-post-processr nil
283 "A functions that makes adjustments to `c-ts-mode--statement-offset'.
284
285This is a function that takes two arguments, the current indent
286level and the current node, and returns a new level.
287
288When `c-ts-mode--statement-offset' runs and go up the parse tree,
289it increments the indent level when some condition are met in
290each level. At each level, after (possibly) incrementing the
291offset, it calls this function, passing it the current indent
292level and the current node, and use the return value as the new
293indent level.")
294
282(defun c-ts-mode--statement-offset (node parent &rest _) 295(defun c-ts-mode--statement-offset (node parent &rest _)
283 "This anchor is used for children of a statement inside a block. 296 "This anchor is used for children of a statement inside a block.
284 297
@@ -319,9 +332,24 @@ PARENT is NODE's parent."
319 ;; Add a level. 332 ;; Add a level.
320 ((looking-back (rx bol (* whitespace)) 333 ((looking-back (rx bol (* whitespace))
321 (line-beginning-position)) 334 (line-beginning-position))
322 (cl-incf level)))))) 335 (cl-incf level)))))
336 (when c-ts-mode--statement-offset-post-processr
337 (setq level (funcall c-ts-mode--statement-offset-post-processr
338 level node))))
323 (* level c-ts-mode-indent-offset))) 339 (* level c-ts-mode-indent-offset)))
324 340
341(defun c-ts-mode--fix-bracketless-indent (level node)
342 "Takes LEVEL and NODE and returns adjusted LEVEL.
343This fixes indentation for cases shown in bug#61026. Basically
344in C/C++, constructs like if, for, while sometimes don't have
345bracket."
346 (if (and (not (equal (treesit-node-type node) "compound_statement"))
347 (member (treesit-node-type (treesit-node-parent node))
348 '("if_statement" "while_statement" "do_statement"
349 "for_statement")))
350 (1+ level)
351 level))
352
325(defun c-ts-mode--close-bracket-offset (node parent &rest _) 353(defun c-ts-mode--close-bracket-offset (node parent &rest _)
326 "Offset for the closing bracket, NODE. 354 "Offset for the closing bracket, NODE.
327It's basically one level less that the statements in the block. 355It's basically one level less that the statements in the block.
@@ -758,6 +786,8 @@ the semicolon. This function skips the semicolon."
758 ;; Indent. 786 ;; Indent.
759 (when (eq c-ts-mode-indent-style 'linux) 787 (when (eq c-ts-mode-indent-style 'linux)
760 (setq-local indent-tabs-mode t)) 788 (setq-local indent-tabs-mode t))
789 (setq-local c-ts-mode--statement-offset-post-processr
790 #'c-ts-mode--fix-bracketless-indent)
761 791
762 ;; Comment 792 ;; Comment
763 (c-ts-common-comment-setup) 793 (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 b8524432d02..67654404a77 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,
105} 105}
106=-=-= 106=-=-=
107 107
108Name: Bracket-less Block-Statement (GNU Style) (bug#61026)
109
110=-=
111int main() {
112 while (true)
113 if (true)
114 {
115 puts ("Hello");
116 }
117 for (int i=0; i<5; i++)
118 if (true)
119 {
120 puts ("Hello");
121 }
122 do
123 if (true)
124 {
125 puts ("Hello");
126 }
127 while (true);
128 if (true)
129 if (true)
130 {
131 puts ("Hello");
132 }
133}
134=-=-=
135
136Name: Bracket-less Block-Statement (Linux Style) (bug#61026)
137
138=-=-=
139int main() {
140 while (true)
141 if (true) {
142 puts ("Hello");
143 }
144 for (int i=0; i<5; i++)
145 if (true) {
146 puts ("Hello");
147 }
148 do
149 if (true) {
150 puts ("Hello");
151 }
152 while (true);
153 if (true)
154 if (true) {
155 puts ("Hello");
156 }
157}
158=-=-=
159
108Name: Multiline Parameter List (bug#60398) 160Name: Multiline Parameter List (bug#60398)
109 161
110=-= 162=-=