emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

emacs-29 f0734e1c0d1: Fix c-ts-mode indent heuristic (bug#67417)


From: Yuan Fu
Subject: emacs-29 f0734e1c0d1: Fix c-ts-mode indent heuristic (bug#67417)
Date: Sun, 10 Dec 2023 04:27:03 -0500 (EST)

branch: emacs-29
commit f0734e1c0d19d9f244b7ab60dcd98f8d031e3d38
Author: Yuan Fu <casouri@gmail.com>
Commit: Yuan Fu <casouri@gmail.com>

    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.
---
 lisp/progmodes/c-ts-mode.el | 30 +++++++++++++++---------------
 1 file 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)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]