bug-gnu-emacs
[Top][All Lists]
Advanced

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

bug#60805: [PATCH] Extend go-ts-mode with command to add docstring to fu


From: Evgeni Kolev
Subject: bug#60805: [PATCH] Extend go-ts-mode with command to add docstring to function
Date: Fri, 20 Jan 2023 11:41:33 +0200

> What about something like this to locate the first comment above a
> defun?
>
> Theo
>
> (defun move-to-top-comment ()
>   (interactive)
>   (save-restriction
>     (narrow-to-defun t)
>     (let ((comments (cdr (treesit-induce-sparse-tree
>                           (treesit-buffer-root-node)
>                           (lambda (n)
>                             (equal (treesit-node-type n)
>                                    "comment"))))))
>       (goto-char
>        (apply #'treesit-node-start (car comments))))))

Thank you for the suggestion Theo, I learned a lot about
treesit-induce-sparse-tree! When I tested your suggestion however, I
found that the tree sitter functions don't take into account the
narrowing, instead they operate on the whole buffer. So the 'comments'
variable holds all the buffer's comments, not just the ones above the
current defun. The suggestion works because (car comments) returns the
top comment in the buffer and goto-char tries to go to it, but is
restricted by the narrowing. In other words, this works as well:

(defun move-to-top-comment ()
  (interactive)
  (save-restriction
    (narrow-to-defun t)
    (goto-char 0)))

I'm providing an updated patch below. The algorithm for finding the
top comment is a while-loop which does (forward-line -1) until the
previous treesit sibling is not a comment.

I've executed 'checkdoc' this time, and added an /etc/NEWS entry.

The patch is below. Any feedback is appreciated!

>From 5cd8a1cb4e491b9db6ed586d88ac79ab52e395f0 Mon Sep 17 00:00:00 2001
From: Evgeni Kolev <evgenysw@gmail.com>
Date: Sat, 14 Jan 2023 08:28:06 +0200
Subject: [PATCH] Extend go-ts-mode with command to add docstring to function

go-ts-mode is extended with command go-ts-mode-docstring which adds
docstring comment to the defun at point. If a comment already exists,
the point is instead moved to the top-most comment line.

* lisp/progmodes/go-ts-mode.el (go-ts-mode): Extend docstring.
(go-ts-mode-docstring): New function.
(go-ts-mode-map): New map variable.
* etc/NEWS: Mention the change.
---
 etc/NEWS                     |  8 ++++++++
 lisp/progmodes/go-ts-mode.el | 30 +++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/etc/NEWS b/etc/NEWS
index cde6783349f..68ad90ab189 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -165,6 +165,14 @@ the new argument non-nil, it will use a new buffer instead.
 Interactively, invoke 'eww-open-file' with a prefix argument to
 activate this behavior.

+** go-ts-mode
+
++++
+*** New command 'go-ts-mode-docstring'.
+This command adds a docstring comment to the current defun.  If a
+comment already exists, point is only moved to the comment.  It is
+bound to 'C-c C-d' in 'go-ts-mode'.
+

 * New Modes and Packages in Emacs 30.1

diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el
index 64e761d2f72..cc8171e9be6 100644
--- a/lisp/progmodes/go-ts-mode.el
+++ b/lisp/progmodes/go-ts-mode.el
@@ -177,9 +177,16 @@ go-ts-mode--font-lock-settings
 ;;;###autoload
 (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode))

+(defvar-keymap go-ts-mode-map
+  :doc "Keymap used in Go mode, powered by tree-sitter"
+  :parent prog-mode-map
+  "C-c C-d" #'go-ts-mode-docstring)
+
 ;;;###autoload
 (define-derived-mode go-ts-mode prog-mode "Go"
-  "Major mode for editing Go, powered by tree-sitter."
+  "Major mode for editing Go, powered by tree-sitter.
+
+\\{go-ts-mode-map}"
   :group 'go
   :syntax-table go-ts-mode--syntax-table

@@ -274,6 +281,27 @@ go-ts-mode--other-type-node-p
    (not (go-ts-mode--struct-node-p node))
    (not (go-ts-mode--alias-node-p node))))

+(defun go-ts-mode-docstring ()
+  "Add a docstring comment for the current defun.
+The added docstring is prefilled with the defun's name.  If the
+comment already exists, jump to it."
+  (interactive)
+  (when-let ((defun-node (treesit-defun-at-point))
+             (defun-name (treesit-defun-name defun-node)))
+    (let ((prev-node (treesit-node-prev-sibling defun-node t)))
+      (if (string-equal "comment" (treesit-node-type prev-node))
+          ;; go to the top-most comment line
+          (progn
+            (goto-char (treesit-node-start prev-node))
+            (while-let ((curr-node (treesit-node-at (point)))
+                        (prev-node (treesit-node-prev-sibling curr-node t))
+                        ((string-equal "comment" (treesit-node-type
prev-node))))
+              (forward-line -1)))
+        (goto-char (treesit-node-start defun-node))
+        (newline)
+        (forward-line -1)
+        (insert "// " defun-name)))))
+
 ;; go.mod support.

 (defvar go-mod-ts-mode--syntax-table
-- 
2.30.2





reply via email to

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