aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornverno2023-11-21 16:33:04 -0800
committerYuan Fu2023-12-10 01:05:22 -0800
commit08fc6bace202a13d93fc76943c41f19acaab9c73 (patch)
tree8cf452ecf590a8df8e08008ecefcdb1795b7a540
parent71bc2815ccdf443d49865ea913048658a6634823 (diff)
downloademacs-08fc6bace202a13d93fc76943c41f19acaab9c73.tar.gz
emacs-08fc6bace202a13d93fc76943c41f19acaab9c73.zip
Fix c-ts-mode indentation (bug#67357)
1. In a compund_statement, we indent the first sibling against the parent, and the rest siblings against their previous sibling. But this strategy falls apart when the first sibling is not on its own line. We should regard the first sibling that is on its own line as the "first sibling"", and indent it against the parent. 2. In linux style, in a do-while statement, if the do-body is bracket-less, the "while" keyword is indented to the same level as the do-body. It should be indented to align with the "do" keyword instead. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--no-prev-standalone-sibling): New function. (c-ts-mode--indent-styles): Use c-ts-mode--no-prev-standalone-sibling. Add while keyword indent rule. * test/lisp/progmodes/c-ts-mode-resources/indent.erts: New tests.
-rw-r--r--lisp/progmodes/c-ts-mode.el23
-rw-r--r--test/lisp/progmodes/c-ts-mode-resources/indent.erts48
2 files changed, 68 insertions, 3 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 21fb0ca9e53..677273afaac 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -321,7 +321,8 @@ PARENT and BOL are like other anchor functions."
321 (treesit-node-parent prev-sibling) t))) 321 (treesit-node-parent prev-sibling) t)))
322 ;; If the start of the previous sibling isn't at the 322 ;; If the start of the previous sibling isn't at the
323 ;; beginning of a line, something's probably not quite 323 ;; beginning of a line, something's probably not quite
324 ;; right, go a step further. 324 ;; right, go a step further. (E.g., comment after a
325 ;; statement.)
325 (_ (goto-char (treesit-node-start prev-sibling)) 326 (_ (goto-char (treesit-node-start prev-sibling))
326 (if (looking-back (rx bol (* whitespace)) 327 (if (looking-back (rx bol (* whitespace))
327 (line-beginning-position)) 328 (line-beginning-position))
@@ -364,6 +365,19 @@ PARENT, BOL, ARGS are the same as other anchor functions."
364 (back-to-indentation) 365 (back-to-indentation)
365 (looking-at-p regexp)))) 366 (looking-at-p regexp))))
366 367
368(defun c-ts-mode--first-sibling (node parent &rest _)
369 "Matches when NODE is the \"first sibling\".
370\"First sibling\" is defined as: the first child node of PARENT
371such that it's on its own line. NODE is the node to match and
372PARENT is its parent."
373 (let ((prev-sibling (treesit-node-prev-sibling node t)))
374 (or (null prev-sibling)
375 (save-excursion
376 (goto-char (treesit-node-start prev-sibling))
377 (<= (line-beginning-position)
378 (treesit-node-start parent)
379 (line-end-position))))))
380
367(defun c-ts-mode--indent-styles (mode) 381(defun c-ts-mode--indent-styles (mode)
368 "Indent rules supported by `c-ts-mode'. 382 "Indent rules supported by `c-ts-mode'.
369MODE is either `c' or `cpp'." 383MODE is either `c' or `cpp'."
@@ -457,7 +471,11 @@ MODE is either `c' or `cpp'."
457 ((parent-is "field_declaration_list") c-ts-mode--anchor-prev-sibling 0) 471 ((parent-is "field_declaration_list") c-ts-mode--anchor-prev-sibling 0)
458 472
459 ;; Statement in {} blocks. 473 ;; Statement in {} blocks.
460 ((or (match nil "compound_statement" nil 1 1) 474 ((or (and (parent-is "compound_statement")
475 ;; If the previous sibling(s) are not on their
476 ;; own line, indent as if this node is the first
477 ;; sibling (Bug#67357)
478 c-ts-mode--first-sibling)
461 (match null "compound_statement")) 479 (match null "compound_statement"))
462 standalone-parent c-ts-mode-indent-offset) 480 standalone-parent c-ts-mode-indent-offset)
463 ((parent-is "compound_statement") c-ts-mode--anchor-prev-sibling 0) 481 ((parent-is "compound_statement") c-ts-mode--anchor-prev-sibling 0)
@@ -470,6 +488,7 @@ MODE is either `c' or `cpp'."
470 ((parent-is "if_statement") standalone-parent c-ts-mode-indent-offset) 488 ((parent-is "if_statement") standalone-parent c-ts-mode-indent-offset)
471 ((parent-is "else_clause") standalone-parent c-ts-mode-indent-offset) 489 ((parent-is "else_clause") standalone-parent c-ts-mode-indent-offset)
472 ((parent-is "for_statement") standalone-parent c-ts-mode-indent-offset) 490 ((parent-is "for_statement") standalone-parent c-ts-mode-indent-offset)
491 ((match "while" "do_statement") parent-bol 0) ; (do_statement "while")
473 ((parent-is "while_statement") standalone-parent c-ts-mode-indent-offset) 492 ((parent-is "while_statement") standalone-parent c-ts-mode-indent-offset)
474 ((parent-is "do_statement") standalone-parent c-ts-mode-indent-offset) 493 ((parent-is "do_statement") standalone-parent c-ts-mode-indent-offset)
475 494
diff --git a/test/lisp/progmodes/c-ts-mode-resources/indent.erts b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
index bac76fb7378..2fd26d75844 100644
--- a/test/lisp/progmodes/c-ts-mode-resources/indent.erts
+++ b/test/lisp/progmodes/c-ts-mode-resources/indent.erts
@@ -330,7 +330,7 @@ label:
330 330
331Name: Bracket-less Block-Statement (Linux Style) (bug#61026) 331Name: Bracket-less Block-Statement (Linux Style) (bug#61026)
332 332
333=-=-= 333=-=
334int main() { 334int main() {
335 while (true) 335 while (true)
336 if (true) { 336 if (true) {
@@ -351,6 +351,8 @@ int main() {
351 if (true) { 351 if (true) {
352 puts ("Hello"); 352 puts ("Hello");
353 } 353 }
354 else
355 puts("Hello");
354} 356}
355=-=-= 357=-=-=
356 358
@@ -399,6 +401,34 @@ void foo(
399} 401}
400=-=-= 402=-=-=
401 403
404Name: Block-Statement where first siblings are comments (Linux Style)
405
406=-=
407int main() {
408 while (true) { /* foo */
409 if (true) { // bar
410 puts ("Hello");
411 }
412 }
413 for (;;) { // 1. fooo
414 /* 2. baaa */
415 /* 3. rrr */
416 if (true)
417 // 2. baaa
418 puts ("Hello");
419 }
420 if (1) { // 1
421 /*
422 * 2
423 */
424 if (1) /*3*/ {
425 /* 4 */
426 puts("Hello");
427 }
428 }
429}
430=-=-=
431
402Name: Initializer List (Linux Style) (Bug#61398) 432Name: Initializer List (Linux Style) (Bug#61398)
403 433
404=-= 434=-=
@@ -498,3 +528,19 @@ main (void)
498{ 528{
499 | 529 |
500=-=-= 530=-=-=
531
532Code:
533 (lambda ()
534 (c-ts-mode)
535 (setq-local indent-tabs-mode nil)
536 (goto-line 3)
537 (indent-for-tab-command))
538
539Name: Block-Statement where previous sibling is comment
540
541=-=
542int main() {
543 puts ("Hello"); // unusual indent and has trailing comment.
544 return true; // Should align with previous non-comment sibling (rather than one level up against parent).
545}
546=-=-=