Subject: bug#77727: [PATCH] Limit rust-ts-specific comment-start check to rust-ts (bug#77727)

From: Konstantin Kharlamov <[email-masked]>
Date: Fri, 11 Apr 2025 14:51:44 +0300

On Fri, 2025-04-11 at 11:34 +0300, Konstantin Kharlamov wrote:
> CC: Yuan Fu as the author of the code in question.
> 
> What happens in the code makes sense: since the comment resides at
> top-
> level, the parent of any top-level statement (returned by (treesit-
> node-parent node)) is, well, beginning of a buffer.
> 
> So the question is, why the check works that way.

Please see the attached patch, it'd seem this is exactly the fix that's
expected here. Basically, the problematic check is specific to Rust
treesitter mode, so shouldn't be executed in other languages. The patch
factors out the entire check to a separate function and adds additional
condition of (eq major-mode 'rust-ts-mode).

Tested in tsx-ts-mode, it fixes the problem.
From c5ceabb373939c30d2f2786f1b06dd0915232148 Mon Sep 17 00:00:00 2001
From: Konstantin Kharlamov <[email-masked]>
Date: Fri, 11 Apr 2025 14:38:24 +0300
Subject: [PATCH] Limit rust-ts-specific comment-start check to rust-ts
 (bug#77727)

The check `(treesit-node-start (treesit-node-parent node))' is
specific to Rust mode (as mentioned in the comment), and in other
languages it was wrong to execute.  E.g. in tsx-ts-mode it was giving
the start of the buffer, and then if buffer started with `//' the
wrong branch of execution was being taken.  Fix that by limiting the
check to rust-ts-mode which is the only one where it matters.

* lisp/progmodes/c-ts-common.el (c-ts-common--fill-paragraph): Factor
out `c-ts-common--comment-start-is-//' and reduce comment length.
(c-ts-common--comment-start-is-//): New function, whose body is taken
from `c-ts-common--fill-paragraph'.  The changes that were done:
1. The rust-specific check is now limited to rust-ts-mode, 2. The
explanation comment is made more explicit.
---
 lisp/progmodes/c-ts-common.el | 27 +++++++++++++++------------
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/lisp/progmodes/c-ts-common.el b/lisp/progmodes/c-ts-common.el
index 71c177788a8..c16a1f0c467 100644
--- a/lisp/progmodes/c-ts-common.el
+++ b/lisp/progmodes/c-ts-common.el
@@ -113,6 +113,19 @@ c-ts-common--comment-regexp
   (rx (or "comment" "line_comment" "block_comment"))
   "Regexp pattern that matches a comment in C-like languages.")
 
+(defun c-ts-common--comment-start-is-// (node)
+  (or (save-excursion
+        (goto-char (treesit-node-start node))
+        (looking-at "//"))
+      ;; In rust, NODE start may be inside the comment, the parent then
+      ;; will be start of the comment.
+      (when-let* ((_ (eq major-mode 'rust-ts-mode))
+                  (start (treesit-node-start
+                          (treesit-node-parent node))))
+        (save-excursion
+          (goto-char start)
+          (looking-at "//")))))
+
 (defun c-ts-common--fill-paragraph (&optional arg)
   "Filling function for `c-ts-common'.
 ARG is passed to `fill-paragraph'."
@@ -122,20 +135,10 @@ c-ts-common--fill-paragraph
     (let ((node (treesit-node-at (point))))
       (when (string-match-p c-ts-common--comment-regexp
                             (treesit-node-type node))
-        (if (or (save-excursion
-                  (goto-char (treesit-node-start node))
-                  (looking-at "//"))
-                ;; In rust, NODE will be the body of a comment, and the
-                ;; parent will be the whole comment.
-                (if-let* ((start (treesit-node-start
-                                  (treesit-node-parent node))))
-                    (save-excursion
-                      (goto-char start)
-                      (looking-at "//"))))
+        (if (c-ts-common--comment-start-is-// node)
             (fill-comment-paragraph arg)
           (c-ts-common--fill-block-comment arg)))
-      ;; Return t so `fill-paragraph' doesn't attempt to fill by
-      ;; itself.
+      ;; Return t so `fill-paragraph' doesn't attempt to fill by itself.
       t)))
 
 (defun c-ts-common--fill-block-comment (&optional arg)
-- 
2.49.0