summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuan Fu <casouri@gmail.com>2023-12-10 01:24:25 -0800
committerYuan Fu <casouri@gmail.com>2023-12-10 01:24:25 -0800
commitf0734e1c0d19d9f244b7ab60dcd98f8d031e3d38 (patch)
treeb432620ad1f4e232ce237e2be6449db7245a3f84
parent08fc6bace202a13d93fc76943c41f19acaab9c73 (diff)
downloademacs-f0734e1c0d1.tar.gz
Fix c-ts-mode indent heuristic (bug#67417)
This is a continuation of the first two patches for bug#67417. The c-ts-mode--prev-line-match heuristic we added is too broad, so for now we are just adding a very specific heuristic for the else case. * lisp/progmodes/c-ts-mode.el: (c-ts-mode--prev-line-match): Remove function. (c-ts-mode--else-heuristic): New function. (c-ts-mode--indent-styles): Use c-ts-mode--else-heuristic.
-rw-r--r--lisp/progmodes/c-ts-mode.el30
1 files changed, 15 insertions, 15 deletions
diff --git a/lisp/progmodes/c-ts-mode.el b/lisp/progmodes/c-ts-mode.el
index 677273afaac..05758d48f52 100644
--- a/lisp/progmodes/c-ts-mode.el
+++ b/lisp/progmodes/c-ts-mode.el
@@ -356,14 +356,15 @@ PARENT, BOL, ARGS are the same as other anchor functions."
(apply (alist-get 'standalone-parent treesit-simple-indent-presets)
parent (treesit-node-parent parent) bol args))
-(defun c-ts-mode--prev-line-match (regexp)
- "An indentation matcher that matches if previous line matches REGEXP."
- (lambda (_n _p bol &rest _)
- (save-excursion
- (goto-char bol)
- (forward-line -1)
- (back-to-indentation)
- (looking-at-p regexp))))
+(defun c-ts-mode--else-heuristic (node parent bol &rest _)
+ "Heuristic matcher for when else is followed by a closing bracket.
+NODE, PARENT, BOL are the same as other matchers."
+ (and (null node)
+ (save-excursion
+ (forward-line -1)
+ (looking-at (rx (* whitespace) "else" (* whitespace) eol)))
+ (let ((next-node (treesit-node-first-child-for-pos parent bol)))
+ (equal (treesit-node-type next-node) "}"))))
(defun c-ts-mode--first-sibling (node parent &rest _)
"Matches when NODE is the \"first sibling\".
@@ -383,13 +384,12 @@ PARENT is its parent."
MODE is either `c' or `cpp'."
(let ((common
`((c-ts-mode--for-each-tail-body-matcher prev-line c-ts-mode-indent-offset)
- ;; If the user types "if (...)" and hits RET, they expect
- ;; point on the empty line to be indented; this rule
- ;; does that.
- ((and no-node
- (c-ts-mode--prev-line-match
- ,(rx (or "if" "else" "while" "do" "for"))))
- prev-line c-ts-mode-indent-offset)
+ ;; If the user types "else" and hits RET, they expect point
+ ;; on the empty line to be indented; this rule does that.
+ ;; This heuristic is intentionally very specific because
+ ;; more general heuristic is very error-prone, see
+ ;; discussion in bug#67417.
+ (c-ts-mode--else-heuristic prev-line c-ts-mode-indent-offset)
((parent-is "translation_unit") column-0 0)
((query "(ERROR (ERROR)) @indent") column-0 0)