diff options
| author | Yuan Fu | 2023-01-25 23:47:27 -0800 |
|---|---|---|
| committer | Yuan Fu | 2023-01-25 23:47:27 -0800 |
| commit | cdf74254ffa2c53612f6d985e3774b51233fbd49 (patch) | |
| tree | d1bc32bc8f622bce15efa9335187b10411d4cfed | |
| parent | 4bd06ce2a9fa1601aff5a5fcab7411e5fce20d28 (diff) | |
| download | emacs-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.el | 32 | ||||
| -rw-r--r-- | test/lisp/progmodes/c-ts-mode-resources/indent.erts | 52 |
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 | |||
| 285 | This is a function that takes two arguments, the current indent | ||
| 286 | level and the current node, and returns a new level. | ||
| 287 | |||
| 288 | When `c-ts-mode--statement-offset' runs and go up the parse tree, | ||
| 289 | it increments the indent level when some condition are met in | ||
| 290 | each level. At each level, after (possibly) incrementing the | ||
| 291 | offset, it calls this function, passing it the current indent | ||
| 292 | level and the current node, and use the return value as the new | ||
| 293 | indent 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. | ||
| 343 | This fixes indentation for cases shown in bug#61026. Basically | ||
| 344 | in C/C++, constructs like if, for, while sometimes don't have | ||
| 345 | bracket." | ||
| 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. |
| 327 | It's basically one level less that the statements in the block. | 355 | It'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 | ||
| 108 | Name: Bracket-less Block-Statement (GNU Style) (bug#61026) | ||
| 109 | |||
| 110 | =-= | ||
| 111 | int 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 | |||
| 136 | Name: Bracket-less Block-Statement (Linux Style) (bug#61026) | ||
| 137 | |||
| 138 | =-=-= | ||
| 139 | int 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 | |||
| 108 | Name: Multiline Parameter List (bug#60398) | 160 | Name: Multiline Parameter List (bug#60398) |
| 109 | 161 | ||
| 110 | =-= | 162 | =-= |