]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix c-ts-mode defun movement (bug#59628)
authorYuan Fu <casouri@gmail.com>
Wed, 30 Nov 2022 22:59:06 +0000 (14:59 -0800)
committerYuan Fu <casouri@gmail.com>
Thu, 1 Dec 2022 00:57:08 +0000 (16:57 -0800)
* lisp/progmodes/c-ts-mode.el (c-ts-mode--end-of-defun): New function.
(c-ts-mode--base-mode): Use more specific regexp, and set
treesit-defun-prefer-top-level.
(c-ts-mode)
(c++-ts-mode): Set end-of-defun-function.

lisp/progmodes/c-ts-mode.el

index a79dabcd312431358acc70531a48412aa239da2b..38e9fff05efe4e819ca2365cbd340ef5a4fd7739 100644 (file)
@@ -505,6 +505,19 @@ the subtrees."
      (when var-index `(("Variable" . ,var-index)))
      (when func-index `(("Function" . ,func-index))))))
 
+(defun c-ts-mode--end-of-defun ()
+  "`end-of-defun-function' of `c-ts-mode'."
+  ;; A struct/enum/union_specifier node doesn't include the ; at the
+  ;; end, so we manually skip it.
+  (treesit-end-of-defun)
+  (when (looking-at (rx (* " ") ";"))
+    (goto-char (match-end 0))
+    ;; This part is copied from `end-of-defun'.
+    (unless (bolp)
+      (skip-chars-forward " \t")
+      (if (looking-at "\\s<\\|\n")
+         (forward-line 1)))))
+
 ;;;###autoload
 (define-derived-mode c-ts-mode--base-mode prog-mode "C"
   "Major mode for editing C, powered by tree-sitter."
@@ -512,8 +525,15 @@ the subtrees."
 
   ;; Navigation.
   (setq-local treesit-defun-type-regexp
-              (rx (or "specifier"
-                      "definition")))
+              (rx (or "function_definition"
+                      "type_definition"
+                      "struct_specifier"
+                      "enum_specifier"
+                      "union_specifier")))
+
+  ;; Nodes like struct/enum/union_specifier can appear in
+  ;; function_definitions, so we need to find the top-level node.
+  (setq-local treesit-defun-prefer-top-level t)
 
   ;; Indent.
   (when (eq c-ts-mode-indent-style 'linux)
@@ -559,7 +579,11 @@ the subtrees."
   ;; Font-lock.
   (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'c))
 
-  (treesit-major-mode-setup))
+  (treesit-major-mode-setup)
+
+  ;; Override default value of end-of-defun-function set by
+  ;; `treesit-major-mode-setup'.
+  (setq-local end-of-defun-function #'c-ts-mode--end-of-defun))
 
 ;;;###autoload
 (define-derived-mode c++-ts-mode c-ts-mode--base-mode "C++"
@@ -587,7 +611,11 @@ the subtrees."
   ;; Font-lock.
   (setq-local treesit-font-lock-settings (c-ts-mode--font-lock-settings 'cpp))
 
-  (treesit-major-mode-setup))
+  (treesit-major-mode-setup)
+
+  ;; Override default value of end-of-defun-function set by
+  ;; `treesit-major-mode-setup'.
+  (setq-local end-of-defun-function #'c-ts-mode--end-of-defun))
 
 (provide 'c-ts-mode)