* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility @ 2022-12-29 16:05 Evgeni Kolev 2023-01-01 9:07 ` Eli Zaretskii ` (2 more replies) 0 siblings, 3 replies; 14+ messages in thread From: Evgeni Kolev @ 2022-12-29 16:05 UTC (permalink / raw) To: 60407 This patch updates go-ts-mode to use Imenu facility added in https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=b39dc7ab27a696a8607ab859aeff3c71509231f5 The Imenu items are extended to support "Method", in addition to "Function" and "Type". The current Imenu approach uses "type_spec" to identify "Type" which acts as a catch-all for many Go constructs, for example struct and interface definitions. This catch-all approach is not optimal because structs and interfaces are put in the same "Type" bucket. In a follow-up patch I'll try to change the approach and have separate "Interface" and "Struct" types. The patch is below. commit 71ff7b21fe92167313bd1761b68b6e6fd879b09f Author: Evgeni Kolev <evgenysw@gmail.com> Date: Thu Dec 29 17:49:40 2022 +0200 Update go-ts-mode to use Imenu facility go-ts-mode is updated to use the Imenu facility added in commit b39dc7ab27a696a8607ab859aeff3c71509231f5. The Imenu items are extended to support "Method", in addition to "Function" and "Type". * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): Remove functions. (go-ts-mode--defun-name): New function. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 124d9b044a2..c6c1c61d9f4 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings '((ERROR) @font-lock-warning-face)) "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index `(("Function" . ,func-index))) - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for `go-ts-mode--imenu'. -Find string representation for NODE and set marker, then recurse -the subtrees." - (let* ((ts-node (car node)) - (children (cdr node)) - (subtrees (mapcan #'go-ts-mode--imenu-1 - children)) - (name (when ts-node - (treesit-node-text - (pcase (treesit-node-type ts-node) - ("function_declaration" - (treesit-node-child-by-field-name ts-node "name")) - ("type_spec" - (treesit-node-child-by-field-name ts-node "name")))))) - (marker (when ts-node - (set-marker (make-marker) - (treesit-node-start ts-node))))) - (cond - ((or (null ts-node) (null name)) subtrees) - (subtrees - `((,name ,(cons name marker) ,@subtrees))) - (t - `((,name . ,marker)))))) - ;;;###autoload (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) @@ -228,9 +190,18 @@ go-ts-mode (setq-local comment-end "") (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + ;; Navigation. + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "function_declaration" + "type_spec"))) + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) + ;; Imenu. - (setq-local imenu-create-index-function #'go-ts-mode--imenu) - (setq-local which-func-functions nil) + (setq-local treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Type" "\\`type_spec\\'" nil nil) + ("Method" "\\`method_declaration\\'" nil nil))) ;; Indent. (setq-local indent-tabs-mode t @@ -247,6 +218,18 @@ go-ts-mode (treesit-major-mode-setup))) +(defun go-ts-mode--defun-name (node) + "Return the defun name of NODE. +Return nil if there is no name or if NODE is not a defun node." + (pcase (treesit-node-type node) + ((or "function_declaration" + "method_declaration" + "type_spec") + (treesit-node-text + (treesit-node-child-by-field-name + node "name") + t)))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2022-12-29 16:05 bug#60407: [PATCH] Update go-ts-mode to use Imenu facility Evgeni Kolev @ 2023-01-01 9:07 ` Eli Zaretskii 2023-01-01 13:05 ` Evgeni Kolev 2023-01-01 13:08 ` Randy Taylor 2023-01-08 0:20 ` Yuan Fu 2023-01-09 0:35 ` Yuan Fu 2 siblings, 2 replies; 14+ messages in thread From: Eli Zaretskii @ 2023-01-01 9:07 UTC (permalink / raw) To: Evgeni Kolev, Randy Taylor; +Cc: 60407, Yuan Fu > From: Evgeni Kolev <evgenysw@gmail.com> > Date: Thu, 29 Dec 2022 18:05:49 +0200 > > This patch updates go-ts-mode to use Imenu facility added in > https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=b39dc7ab27a696a8607ab859aeff3c71509231f5 > > The Imenu items are extended to support "Method", in addition to > "Function" and "Type". > > The current Imenu approach uses "type_spec" to identify "Type" which > acts as a catch-all for many Go constructs, for example struct and > interface definitions. This catch-all approach is not optimal because > structs and interfaces are put in the same "Type" bucket. In a > follow-up patch I'll try to change the approach and have separate > "Interface" and "Struct" types. > > The patch is below. Randy, Yuan, are you looking into this? > commit 71ff7b21fe92167313bd1761b68b6e6fd879b09f > Author: Evgeni Kolev <evgenysw@gmail.com> > Date: Thu Dec 29 17:49:40 2022 +0200 > > Update go-ts-mode to use Imenu facility > > go-ts-mode is updated to use the Imenu facility added in commit > b39dc7ab27a696a8607ab859aeff3c71509231f5. > > The Imenu items are extended to support "Method", in addition to > "Function" and "Type". > > * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): > Remove functions. > (go-ts-mode--defun-name): New function. > > diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el > index 124d9b044a2..c6c1c61d9f4 100644 > --- a/lisp/progmodes/go-ts-mode.el > +++ b/lisp/progmodes/go-ts-mode.el > @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings > '((ERROR) @font-lock-warning-face)) > "Tree-sitter font-lock settings for `go-ts-mode'.") > > -(defun go-ts-mode--imenu () > - "Return Imenu alist for the current buffer." > - (let* ((node (treesit-buffer-root-node)) > - (func-tree (treesit-induce-sparse-tree > - node "function_declaration" nil 1000)) > - (type-tree (treesit-induce-sparse-tree > - node "type_spec" nil 1000)) > - (func-index (go-ts-mode--imenu-1 func-tree)) > - (type-index (go-ts-mode--imenu-1 type-tree))) > - (append > - (when func-index `(("Function" . ,func-index))) > - (when type-index `(("Type" . ,type-index)))))) > - > -(defun go-ts-mode--imenu-1 (node) > - "Helper for `go-ts-mode--imenu'. > -Find string representation for NODE and set marker, then recurse > -the subtrees." > - (let* ((ts-node (car node)) > - (children (cdr node)) > - (subtrees (mapcan #'go-ts-mode--imenu-1 > - children)) > - (name (when ts-node > - (treesit-node-text > - (pcase (treesit-node-type ts-node) > - ("function_declaration" > - (treesit-node-child-by-field-name ts-node "name")) > - ("type_spec" > - (treesit-node-child-by-field-name ts-node "name")))))) > - (marker (when ts-node > - (set-marker (make-marker) > - (treesit-node-start ts-node))))) > - (cond > - ((or (null ts-node) (null name)) subtrees) > - (subtrees > - `((,name ,(cons name marker) ,@subtrees))) > - (t > - `((,name . ,marker)))))) > - > ;;;###autoload > (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) > > @@ -228,9 +190,18 @@ go-ts-mode > (setq-local comment-end "") > (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) > > + ;; Navigation. > + (setq-local treesit-defun-type-regexp > + (regexp-opt '("method_declaration" > + "function_declaration" > + "type_spec"))) > + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) > + > ;; Imenu. > - (setq-local imenu-create-index-function #'go-ts-mode--imenu) > - (setq-local which-func-functions nil) > + (setq-local treesit-simple-imenu-settings > + `(("Function" "\\`function_declaration\\'" nil nil) > + ("Type" "\\`type_spec\\'" nil nil) > + ("Method" "\\`method_declaration\\'" nil nil))) > > ;; Indent. > (setq-local indent-tabs-mode t > @@ -247,6 +218,18 @@ go-ts-mode > > (treesit-major-mode-setup))) > > +(defun go-ts-mode--defun-name (node) > + "Return the defun name of NODE. > +Return nil if there is no name or if NODE is not a defun node." > + (pcase (treesit-node-type node) > + ((or "function_declaration" > + "method_declaration" > + "type_spec") > + (treesit-node-text > + (treesit-node-child-by-field-name > + node "name") > + t)))) > + > ;; go.mod support. > > (defvar go-mod-ts-mode--syntax-table > > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-01 9:07 ` Eli Zaretskii @ 2023-01-01 13:05 ` Evgeni Kolev 2023-01-01 17:08 ` Evgeni Kolev 2023-01-01 13:08 ` Randy Taylor 1 sibling, 1 reply; 14+ messages in thread From: Evgeni Kolev @ 2023-01-01 13:05 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Randy Taylor, 60407, Yuan Fu To illustrate the change, here's a comparison before VS after (VS eglot). I'm using a sample .go file (at the bottom of this mail). Before: 4 candidates: Function: measure Type: geometry Type: rect Type: circle After: 8 candidates: Function: measure Type: geometry Type: rect Type: circle Method: area Method: perim Method: area Method: perim For comparison, here's eglot's Imenu (using Go's gopls language server): 13 candidates: Interface: geometry Struct: rect Struct: circle Field.rect: width Field.rect: height Field.circle: radius Method.geometry: area Method.geometry: perim Method: (rect).area Method: (rect).perim Method: (circle).area Method: (circle).perim Function: measure Sample .go file: > type geometry interface { > area() float64 > perim() float64 > } > > type rect struct { > width, height float64 > } > > type circle struct { > radius float64 > } > > func (r rect) area() float64 { > return r.width * r.height > } > > func (r rect) perim() float64 { > return 2*r.width + 2*r.height > } > > func (c circle) area() float64 { > return math.Pi * c.radius * c.radius > } > > func (c circle) perim() float64 { > return 2 * math.Pi * c.radius > } > > func measure(g geometry) { > fmt.Println(g) > fmt.Println(g.area()) > fmt.Println(g.perim()) > } On Sun, Jan 1, 2023 at 11:07 AM Eli Zaretskii <eliz@gnu.org> wrote: > > > From: Evgeni Kolev <evgenysw@gmail.com> > > Date: Thu, 29 Dec 2022 18:05:49 +0200 > > > > This patch updates go-ts-mode to use Imenu facility added in > > https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=b39dc7ab27a696a8607ab859aeff3c71509231f5 > > > > The Imenu items are extended to support "Method", in addition to > > "Function" and "Type". > > > > The current Imenu approach uses "type_spec" to identify "Type" which > > acts as a catch-all for many Go constructs, for example struct and > > interface definitions. This catch-all approach is not optimal because > > structs and interfaces are put in the same "Type" bucket. In a > > follow-up patch I'll try to change the approach and have separate > > "Interface" and "Struct" types. > > > > The patch is below. > > Randy, Yuan, are you looking into this? > > > commit 71ff7b21fe92167313bd1761b68b6e6fd879b09f > > Author: Evgeni Kolev <evgenysw@gmail.com> > > Date: Thu Dec 29 17:49:40 2022 +0200 > > > > Update go-ts-mode to use Imenu facility > > > > go-ts-mode is updated to use the Imenu facility added in commit > > b39dc7ab27a696a8607ab859aeff3c71509231f5. > > > > The Imenu items are extended to support "Method", in addition to > > "Function" and "Type". > > > > * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): > > Remove functions. > > (go-ts-mode--defun-name): New function. > > > > diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el > > index 124d9b044a2..c6c1c61d9f4 100644 > > --- a/lisp/progmodes/go-ts-mode.el > > +++ b/lisp/progmodes/go-ts-mode.el > > @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings > > '((ERROR) @font-lock-warning-face)) > > "Tree-sitter font-lock settings for `go-ts-mode'.") > > > > -(defun go-ts-mode--imenu () > > - "Return Imenu alist for the current buffer." > > - (let* ((node (treesit-buffer-root-node)) > > - (func-tree (treesit-induce-sparse-tree > > - node "function_declaration" nil 1000)) > > - (type-tree (treesit-induce-sparse-tree > > - node "type_spec" nil 1000)) > > - (func-index (go-ts-mode--imenu-1 func-tree)) > > - (type-index (go-ts-mode--imenu-1 type-tree))) > > - (append > > - (when func-index `(("Function" . ,func-index))) > > - (when type-index `(("Type" . ,type-index)))))) > > - > > -(defun go-ts-mode--imenu-1 (node) > > - "Helper for `go-ts-mode--imenu'. > > -Find string representation for NODE and set marker, then recurse > > -the subtrees." > > - (let* ((ts-node (car node)) > > - (children (cdr node)) > > - (subtrees (mapcan #'go-ts-mode--imenu-1 > > - children)) > > - (name (when ts-node > > - (treesit-node-text > > - (pcase (treesit-node-type ts-node) > > - ("function_declaration" > > - (treesit-node-child-by-field-name ts-node "name")) > > - ("type_spec" > > - (treesit-node-child-by-field-name ts-node "name")))))) > > - (marker (when ts-node > > - (set-marker (make-marker) > > - (treesit-node-start ts-node))))) > > - (cond > > - ((or (null ts-node) (null name)) subtrees) > > - (subtrees > > - `((,name ,(cons name marker) ,@subtrees))) > > - (t > > - `((,name . ,marker)))))) > > - > > ;;;###autoload > > (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) > > > > @@ -228,9 +190,18 @@ go-ts-mode > > (setq-local comment-end "") > > (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) > > > > + ;; Navigation. > > + (setq-local treesit-defun-type-regexp > > + (regexp-opt '("method_declaration" > > + "function_declaration" > > + "type_spec"))) > > + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) > > + > > ;; Imenu. > > - (setq-local imenu-create-index-function #'go-ts-mode--imenu) > > - (setq-local which-func-functions nil) > > + (setq-local treesit-simple-imenu-settings > > + `(("Function" "\\`function_declaration\\'" nil nil) > > + ("Type" "\\`type_spec\\'" nil nil) > > + ("Method" "\\`method_declaration\\'" nil nil))) > > > > ;; Indent. > > (setq-local indent-tabs-mode t > > @@ -247,6 +218,18 @@ go-ts-mode > > > > (treesit-major-mode-setup))) > > > > +(defun go-ts-mode--defun-name (node) > > + "Return the defun name of NODE. > > +Return nil if there is no name or if NODE is not a defun node." > > + (pcase (treesit-node-type node) > > + ((or "function_declaration" > > + "method_declaration" > > + "type_spec") > > + (treesit-node-text > > + (treesit-node-child-by-field-name > > + node "name") > > + t)))) > > + > > ;; go.mod support. > > > > (defvar go-mod-ts-mode--syntax-table > > > > > > > > ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-01 13:05 ` Evgeni Kolev @ 2023-01-01 17:08 ` Evgeni Kolev 2023-01-01 22:31 ` Randy Taylor 0 siblings, 1 reply; 14+ messages in thread From: Evgeni Kolev @ 2023-01-01 17:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Randy Taylor, 60407, Yuan Fu As I mentioned in the start of the mail thread - go-ts-mode's Imenu puts Go interfaces and structs in the same "Type" bucket. This can be improved in go-ts-mode. I'm providing a second patch below which splits the interfaces and structs into their own Imenu categories. Please let me know if I should provide the second patch later, in a separate thread, after the first patch is finished. I'm assuming it's simpler to review the patches together. If it's not - I'll provide them in a way to make the review easier, just let me know. The second patch is below. commit a5c4a0b25e0385516ad1f8c3444830111d467843 Author: Evgeni Kolev <evgenysw@gmail.com> Date: Sun Jan 1 18:57:26 2023 +0200 Improve go-ts-mode Imenu go-ts-mode Imenu is improved to distinguish between Go interfaces and structs. Previously both were put in "Type" category. Now each has its own category: "Interface" and "Struct" respectively. * lisp/progmodes/go-ts-mode.el (go-ts-mode--interface-node-p) (go-ts-mode--struct-node-p): New functions. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index c6c1c61d9f4..cb8d740727a 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -194,13 +194,14 @@ go-ts-mode (setq-local treesit-defun-type-regexp (regexp-opt '("method_declaration" "function_declaration" - "type_spec"))) + "type_declaration"))) (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) ;; Imenu. (setq-local treesit-simple-imenu-settings `(("Function" "\\`function_declaration\\'" nil nil) - ("Type" "\\`type_spec\\'" nil nil) + ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil) + ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil) ("Method" "\\`method_declaration\\'" nil nil))) ;; Indent. @@ -223,13 +224,30 @@ go-ts-mode--defun-name Return nil if there is no name or if NODE is not a defun node." (pcase (treesit-node-type node) ((or "function_declaration" - "method_declaration" - "type_spec") + "method_declaration") (treesit-node-text (treesit-node-child-by-field-name node "name") + t)) + ((or "type_declaration") + (treesit-node-text + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "name") t)))) +(defun go-ts-mode--interface-node-p (node) + "Return t if NODE is a Go interface." + (string-equal "interface_type" + (treesit-node-type + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "type")))) + +(defun go-ts-mode--struct-node-p (node) + "Return t if NODE is a Go struct" + (string-equal "struct_type" (treesit-node-type + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "type")))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table On Sun, Jan 1, 2023 at 3:05 PM Evgeni Kolev <evgenysw@gmail.com> wrote: > > To illustrate the change, here's a comparison before VS after (VS eglot). > > I'm using a sample .go file (at the bottom of this mail). > > Before: > 4 candidates: > Function: measure > Type: geometry > Type: rect > Type: circle > > After: > 8 candidates: > Function: measure > Type: geometry > Type: rect > Type: circle > Method: area > Method: perim > Method: area > Method: perim > > For comparison, here's eglot's Imenu (using Go's gopls language server): > 13 candidates: > Interface: geometry > Struct: rect > Struct: circle > Field.rect: width > Field.rect: height > Field.circle: radius > Method.geometry: area > Method.geometry: perim > Method: (rect).area > Method: (rect).perim > Method: (circle).area > Method: (circle).perim > Function: measure > > Sample .go file: > > > type geometry interface { > > area() float64 > > perim() float64 > > } > > > > type rect struct { > > width, height float64 > > } > > > > type circle struct { > > radius float64 > > } > > > > func (r rect) area() float64 { > > return r.width * r.height > > } > > > > func (r rect) perim() float64 { > > return 2*r.width + 2*r.height > > } > > > > func (c circle) area() float64 { > > return math.Pi * c.radius * c.radius > > } > > > > func (c circle) perim() float64 { > > return 2 * math.Pi * c.radius > > } > > > > func measure(g geometry) { > > fmt.Println(g) > > fmt.Println(g.area()) > > fmt.Println(g.perim()) > > } > > On Sun, Jan 1, 2023 at 11:07 AM Eli Zaretskii <eliz@gnu.org> wrote: > > > > > From: Evgeni Kolev <evgenysw@gmail.com> > > > Date: Thu, 29 Dec 2022 18:05:49 +0200 > > > > > > This patch updates go-ts-mode to use Imenu facility added in > > > https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=b39dc7ab27a696a8607ab859aeff3c71509231f5 > > > > > > The Imenu items are extended to support "Method", in addition to > > > "Function" and "Type". > > > > > > The current Imenu approach uses "type_spec" to identify "Type" which > > > acts as a catch-all for many Go constructs, for example struct and > > > interface definitions. This catch-all approach is not optimal because > > > structs and interfaces are put in the same "Type" bucket. In a > > > follow-up patch I'll try to change the approach and have separate > > > "Interface" and "Struct" types. > > > > > > The patch is below. > > > > Randy, Yuan, are you looking into this? > > > > > commit 71ff7b21fe92167313bd1761b68b6e6fd879b09f > > > Author: Evgeni Kolev <evgenysw@gmail.com> > > > Date: Thu Dec 29 17:49:40 2022 +0200 > > > > > > Update go-ts-mode to use Imenu facility > > > > > > go-ts-mode is updated to use the Imenu facility added in commit > > > b39dc7ab27a696a8607ab859aeff3c71509231f5. > > > > > > The Imenu items are extended to support "Method", in addition to > > > "Function" and "Type". > > > > > > * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): > > > Remove functions. > > > (go-ts-mode--defun-name): New function. > > > > > > diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el > > > index 124d9b044a2..c6c1c61d9f4 100644 > > > --- a/lisp/progmodes/go-ts-mode.el > > > +++ b/lisp/progmodes/go-ts-mode.el > > > @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings > > > '((ERROR) @font-lock-warning-face)) > > > "Tree-sitter font-lock settings for `go-ts-mode'.") > > > > > > -(defun go-ts-mode--imenu () > > > - "Return Imenu alist for the current buffer." > > > - (let* ((node (treesit-buffer-root-node)) > > > - (func-tree (treesit-induce-sparse-tree > > > - node "function_declaration" nil 1000)) > > > - (type-tree (treesit-induce-sparse-tree > > > - node "type_spec" nil 1000)) > > > - (func-index (go-ts-mode--imenu-1 func-tree)) > > > - (type-index (go-ts-mode--imenu-1 type-tree))) > > > - (append > > > - (when func-index `(("Function" . ,func-index))) > > > - (when type-index `(("Type" . ,type-index)))))) > > > - > > > -(defun go-ts-mode--imenu-1 (node) > > > - "Helper for `go-ts-mode--imenu'. > > > -Find string representation for NODE and set marker, then recurse > > > -the subtrees." > > > - (let* ((ts-node (car node)) > > > - (children (cdr node)) > > > - (subtrees (mapcan #'go-ts-mode--imenu-1 > > > - children)) > > > - (name (when ts-node > > > - (treesit-node-text > > > - (pcase (treesit-node-type ts-node) > > > - ("function_declaration" > > > - (treesit-node-child-by-field-name ts-node "name")) > > > - ("type_spec" > > > - (treesit-node-child-by-field-name ts-node "name")))))) > > > - (marker (when ts-node > > > - (set-marker (make-marker) > > > - (treesit-node-start ts-node))))) > > > - (cond > > > - ((or (null ts-node) (null name)) subtrees) > > > - (subtrees > > > - `((,name ,(cons name marker) ,@subtrees))) > > > - (t > > > - `((,name . ,marker)))))) > > > - > > > ;;;###autoload > > > (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) > > > > > > @@ -228,9 +190,18 @@ go-ts-mode > > > (setq-local comment-end "") > > > (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) > > > > > > + ;; Navigation. > > > + (setq-local treesit-defun-type-regexp > > > + (regexp-opt '("method_declaration" > > > + "function_declaration" > > > + "type_spec"))) > > > + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) > > > + > > > ;; Imenu. > > > - (setq-local imenu-create-index-function #'go-ts-mode--imenu) > > > - (setq-local which-func-functions nil) > > > + (setq-local treesit-simple-imenu-settings > > > + `(("Function" "\\`function_declaration\\'" nil nil) > > > + ("Type" "\\`type_spec\\'" nil nil) > > > + ("Method" "\\`method_declaration\\'" nil nil))) > > > > > > ;; Indent. > > > (setq-local indent-tabs-mode t > > > @@ -247,6 +218,18 @@ go-ts-mode > > > > > > (treesit-major-mode-setup))) > > > > > > +(defun go-ts-mode--defun-name (node) > > > + "Return the defun name of NODE. > > > +Return nil if there is no name or if NODE is not a defun node." > > > + (pcase (treesit-node-type node) > > > + ((or "function_declaration" > > > + "method_declaration" > > > + "type_spec") > > > + (treesit-node-text > > > + (treesit-node-child-by-field-name > > > + node "name") > > > + t)))) > > > + > > > ;; go.mod support. > > > > > > (defvar go-mod-ts-mode--syntax-table > > > > > > > > > > > > ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-01 17:08 ` Evgeni Kolev @ 2023-01-01 22:31 ` Randy Taylor 2023-01-03 9:01 ` Evgeni Kolev 0 siblings, 1 reply; 14+ messages in thread From: Randy Taylor @ 2023-01-01 22:31 UTC (permalink / raw) To: Evgeni Kolev; +Cc: Eli Zaretskii, Yuan Fu, 60407 On Sunday, January 1st, 2023 at 12:08, Evgeni Kolev <evgenysw@gmail.com> wrote: > > As I mentioned in the start of the mail thread - go-ts-mode's Imenu > puts Go interfaces and structs in the same "Type" bucket. This can be > improved in go-ts-mode. > > I'm providing a second patch below which splits the interfaces and > structs into their own Imenu categories. > > Please let me know if I should provide the second patch later, in a > separate thread, after the first patch is finished. I'm assuming it's > simpler to review the patches together. If it's not - I'll provide > them in a way to make the review easier, just let me know. > Hi Evgeni! Thanks for working on this, and apologies for the delay. The patches look good to me and work well, except for one issue (and a few minor nits) mentioned below. All in one patch is probably best. - Type definitions are no longer captured. For example: type Quack int Does not show up anymore. - go-ts-mode--struct-node-p's docstring is missing a period at the end. - In go-ts-mode--interface-node-p and go-ts-mode--struct-node-p's docstrings, I'm not sure it's worthwhile to mention "Go". Just interface and struct should be fine. - Should the commit message mention changes to go-ts-mode (as in the actual define-derived-mode mode part)? ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-01 22:31 ` Randy Taylor @ 2023-01-03 9:01 ` Evgeni Kolev 2023-01-03 14:30 ` Randy Taylor 0 siblings, 1 reply; 14+ messages in thread From: Evgeni Kolev @ 2023-01-03 9:01 UTC (permalink / raw) To: Randy Taylor; +Cc: Eli Zaretskii, Yuan Fu, 60407 Hi Randy, thank you for your feedback! I'm providing an updated patch below. I tested with "type Quack int" and other cases such as: type MyInt = int type Option func(s string) type List[T any] struct { head, tail *element[T] } type Number interface { int64 | float64 } After experimenting, I decided to add additional Imenu categories: "Alias" and "Type". So the final list of newly added categories is "Method", "Struct", "Interface", "Alias" and "Type". Structs and interfaces are technically a private case for "Type", but are put in their own Imenu category. Hence the "Type" category now holds all types except structs, interfaces and aliases (aliases have their own tree sitter type defined in Go's grammar.js). For reference, eglot's Imenu uses category "Class" instead of "Type". But I decided to not replicate this behavior - "Class" is not a widely used Go concept. However, I decided to replicate another eglot behaviour - prefixing the method names with the type of the receiver (for example, "(rect).area" for "func (r rect) area() float64..."). I've also addressed the other comments. I'm a bit unsure how the git commit should be formatted - the part of the message which describes changed functions/files. Please let me know if the patch can be improved. The patch is below. commit a96e70052a79881ac666ab699ffd63ed916eaf83 Author: Evgeni Kolev <evgenysw@gmail.com> Date: Thu Dec 29 17:49:40 2022 +0200 Improve go-ts-mode Imenu The Imenu items are extended to support "Method", "Struct", "Interface", "Alias" and "Type". go-ts-mode is updated to use the Imenu facility added in commit b39dc7ab27a696a8607ab859aeff3c71509231f5. * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): Remove functions. (go-ts-mode--defun-name) (go-ts-mode--interface-node-p) (go-ts-mode--struct-node-p) (go-ts-mode--other-type-node-p) (go-ts-mode--alias-node-p): New functions. (go-ts-mode): Improve Imenu settings. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 1d6a8a30db5..d91b555e03e 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings '((ERROR) @font-lock-warning-face)) "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index `(("Function" . ,func-index))) - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for `go-ts-mode--imenu'. -Find string representation for NODE and set marker, then recurse -the subtrees." - (let* ((ts-node (car node)) - (children (cdr node)) - (subtrees (mapcan #'go-ts-mode--imenu-1 - children)) - (name (when ts-node - (treesit-node-text - (pcase (treesit-node-type ts-node) - ("function_declaration" - (treesit-node-child-by-field-name ts-node "name")) - ("type_spec" - (treesit-node-child-by-field-name ts-node "name")))))) - (marker (when ts-node - (set-marker (make-marker) - (treesit-node-start ts-node))))) - (cond - ((or (null ts-node) (null name)) subtrees) - (subtrees - `((,name ,(cons name marker) ,@subtrees))) - (t - `((,name . ,marker)))))) - ;;;###autoload (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) @@ -228,9 +190,21 @@ go-ts-mode (setq-local comment-end "") (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + ;; Navigation. + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "function_declaration" + "type_declaration"))) + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) + ;; Imenu. - (setq-local imenu-create-index-function #'go-ts-mode--imenu) - (setq-local which-func-functions nil) + (setq-local treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Method" "\\`method_declaration\\'" nil nil) + ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil) + ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\`type_declaration\\'" go-ts-mode--other-type-node-p nil) + ("Alias" "\\`type_declaration\\'" go-ts-mode--alias-node-p nil))) ;; Indent. (setq-local indent-tabs-mode t @@ -247,6 +221,53 @@ go-ts-mode (treesit-major-mode-setup))) +(defun go-ts-mode--defun-name (node) + "Return the defun name of NODE. +Return nil if there is no name or if NODE is not a defun node." + (pcase (treesit-node-type node) + ("function_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + node "name") + t)) + ("method_declaration" + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) + (type-node (treesit-search-subtree receiver-node "type_identifier")) + (name-node (treesit-node-child-by-field-name node "name"))) + (concat + "(" (treesit-node-text type-node) ")." + (treesit-node-text name-node)))) + ("type_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "name") + t)))) + +(defun go-ts-mode--interface-node-p (node) + "Return t if NODE is an interface." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "interface_type" nil nil 2))) + +(defun go-ts-mode--struct-node-p (node) + "Return t if NODE is a struct." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "struct_type" nil nil 2))) + +(defun go-ts-mode--alias-node-p (node) + "Return t if NODE is a type alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "type_alias" nil nil 1))) + +(defun go-ts-mode--other-type-node-p (node) + "Return t if NODE is a type, other than interface or struct." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (not (go-ts-mode--interface-node-p node)) + (not (go-ts-mode--struct-node-p node)))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table On Mon, Jan 2, 2023 at 12:31 AM Randy Taylor <dev@rjt.dev> wrote: > > On Sunday, January 1st, 2023 at 12:08, Evgeni Kolev <evgenysw@gmail.com> wrote: > > > > As I mentioned in the start of the mail thread - go-ts-mode's Imenu > > puts Go interfaces and structs in the same "Type" bucket. This can be > > improved in go-ts-mode. > > > > I'm providing a second patch below which splits the interfaces and > > structs into their own Imenu categories. > > > > Please let me know if I should provide the second patch later, in a > > separate thread, after the first patch is finished. I'm assuming it's > > simpler to review the patches together. If it's not - I'll provide > > them in a way to make the review easier, just let me know. > > > > Hi Evgeni! > > Thanks for working on this, and apologies for the delay. > > The patches look good to me and work well, except for one issue (and a few minor nits) mentioned below. All in one patch is probably best. > > - Type definitions are no longer captured. For example: > type Quack int > Does not show up anymore. > - go-ts-mode--struct-node-p's docstring is missing a period at the end. > - In go-ts-mode--interface-node-p and go-ts-mode--struct-node-p's docstrings, I'm not sure it's worthwhile to mention "Go". Just interface and struct should be fine. > - Should the commit message mention changes to go-ts-mode (as in the actual define-derived-mode mode part)? ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-03 9:01 ` Evgeni Kolev @ 2023-01-03 14:30 ` Randy Taylor 2023-01-05 7:24 ` Evgeni Kolev 0 siblings, 1 reply; 14+ messages in thread From: Randy Taylor @ 2023-01-03 14:30 UTC (permalink / raw) To: Evgeni Kolev; +Cc: Eli Zaretskii, Yuan Fu, 60407 On Tuesday, January 3rd, 2023 at 04:01, Evgeni Kolev <evgenysw@gmail.com> wrote: > > Hi Randy, thank you for your feedback! > > I'm providing an updated patch below. I tested with "type Quack int" > and other cases such as: > type MyInt = int > type Option func(s string) > type List[T any] struct { > head, tail *element[T] > } > type Number interface { > int64 | float64 > } > > After experimenting, I decided to add additional Imenu categories: > "Alias" and "Type". > So the final list of newly added categories is "Method", "Struct", > "Interface", "Alias" and "Type". Sounds good to me. It looks like the alias type MyInt = int shows up in both categories: Alias and Type. It should probably belong just in the Alias category. > > Structs and interfaces are technically a private case for "Type", but > are put in their own Imenu category. > Hence the "Type" category now holds all types except structs, > interfaces and aliases (aliases have their own tree sitter type > defined in Go's grammar.js). > > For reference, eglot's Imenu uses category "Class" instead of "Type". > But I decided to not replicate this behavior - "Class" is not a widely > used Go concept. > However, I decided to replicate another eglot behaviour - prefixing > the method names with the type of the receiver (for example, > "(rect).area" for "func (r rect) area() float64..."). Great! I was going to suggest that but forgot. > > I've also addressed the other comments. I'm a bit unsure how the git > commit should be formatted - the part of the message which describes > changed functions/files. > > Please let me know if the patch can be improved. The patch is below. Comments below. > > commit a96e70052a79881ac666ab699ffd63ed916eaf83 > Author: Evgeni Kolev evgenysw@gmail.com > > Date: Thu Dec 29 17:49:40 2022 +0200 > > Improve go-ts-mode Imenu Maybe this should also say "and add navigation support" (or something similar)? > > The Imenu items are extended to support "Method", "Struct", > "Interface", "Alias" and "Type". > > go-ts-mode is updated to use the Imenu facility added in commit > b39dc7ab27a696a8607ab859aeff3c71509231f5. > > * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): > Remove functions. > (go-ts-mode--defun-name) (go-ts-mode--interface-node-p) I'm no commit format expert, but I think this can be (go-ts-mode--defun-name, go-ts-mode--interface-node-p) Whenever it fits on a single line, you can combine them like that. Same for the line below. > (go-ts-mode--struct-node-p) (go-ts-mode--other-type-node-p) > (go-ts-mode--alias-node-p): New functions. > (go-ts-mode): Improve Imenu settings. I think the (go-ts-mode) part should mention that navigation support was added. > > diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el > index 1d6a8a30db5..d91b555e03e 100644 > --- a/lisp/progmodes/go-ts-mode.el > +++ b/lisp/progmodes/go-ts-mode.el > @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings > '((ERROR) @font-lock-warning-face)) > "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index` (("Function" . ,func-index))) > - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for` go-ts-mode--imenu'. > -Find string representation for NODE and set marker, then recurse > -the subtrees." > - (let* ((ts-node (car node)) > - (children (cdr node)) > - (subtrees (mapcan #'go-ts-mode--imenu-1 > - children)) > - (name (when ts-node > - (treesit-node-text > - (pcase (treesit-node-type ts-node) > - ("function_declaration" > - (treesit-node-child-by-field-name ts-node "name")) > - ("type_spec" > - (treesit-node-child-by-field-name ts-node "name")))))) > - (marker (when ts-node > - (set-marker (make-marker) > - (treesit-node-start ts-node))))) > - (cond > - ((or (null ts-node) (null name)) subtrees) > - (subtrees > - `((,name ,(cons name marker) ,@subtrees))) - (t -` ((,name . ,marker)))))) > - > ;;;###autoload > (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) > > @@ -228,9 +190,21 @@ go-ts-mode > (setq-local comment-end "") > (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) > > + ;; Navigation. > + (setq-local treesit-defun-type-regexp > + (regexp-opt '("method_declaration" > + "function_declaration" > + "type_declaration"))) > + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) > + > ;; Imenu. > - (setq-local imenu-create-index-function #'go-ts-mode--imenu) > - (setq-local which-func-functions nil) > + (setq-local treesit-simple-imenu-settings > + `(("Function" "\\\\`function_declaration\\'" nil nil) > + ("Method" "\\`method_declaration\\\\'" nil nil) + ("Struct" "\\\\`type_declaration\\'" > go-ts-mode--struct-node-p nil) > + ("Interface" "\\`type_declaration\\\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\\\`type_declaration\\'" > go-ts-mode--other-type-node-p nil) > + ("Alias" "\\`type_declaration\\'" > go-ts-mode--alias-node-p nil))) > > ;; Indent. > (setq-local indent-tabs-mode t > @@ -247,6 +221,53 @@ go-ts-mode > > (treesit-major-mode-setup))) > > +(defun go-ts-mode--defun-name (node) > + "Return the defun name of NODE. > +Return nil if there is no name or if NODE is not a defun node." > + (pcase (treesit-node-type node) > + ("function_declaration" > + (treesit-node-text > + (treesit-node-child-by-field-name > + node "name") > + t)) > + ("method_declaration" > + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) > + (type-node (treesit-search-subtree receiver-node > "type_identifier")) > + (name-node (treesit-node-child-by-field-name node "name"))) > + (concat > + "(" (treesit-node-text type-node) ")." > + (treesit-node-text name-node)))) > + ("type_declaration" > + (treesit-node-text > + (treesit-node-child-by-field-name > + (treesit-node-child node 0 t) "name") > + t)))) > + > +(defun go-ts-mode--interface-node-p (node) > + "Return t if NODE is an interface." > + (and > + (string-equal "type_declaration" (treesit-node-type node)) > + (treesit-search-subtree node "interface_type" nil nil 2))) I think you need to add (declare-function treesit-search-subtree "treesit.c") after the last one at the top of the file. > + > +(defun go-ts-mode--struct-node-p (node) > + "Return t if NODE is a struct." > + (and > + (string-equal "type_declaration" (treesit-node-type node)) > + (treesit-search-subtree node "struct_type" nil nil 2))) > + > +(defun go-ts-mode--alias-node-p (node) > + "Return t if NODE is a type alias." > + (and > + (string-equal "type_declaration" (treesit-node-type node)) > + (treesit-search-subtree node "type_alias" nil nil 1))) > + > +(defun go-ts-mode--other-type-node-p (node) > + "Return t if NODE is a type, other than interface or struct." > + (and > + (string-equal "type_declaration" (treesit-node-type node)) > + (not (go-ts-mode--interface-node-p node)) > + (not (go-ts-mode--struct-node-p node)))) Here I guess we just need a (not alias) (and the docstring updated) to fix the issue mentioned above. > + > ;; go.mod support. > > (defvar go-mod-ts-mode--syntax-table > ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-03 14:30 ` Randy Taylor @ 2023-01-05 7:24 ` Evgeni Kolev 2023-01-05 14:21 ` Randy Taylor 0 siblings, 1 reply; 14+ messages in thread From: Evgeni Kolev @ 2023-01-05 7:24 UTC (permalink / raw) To: Randy Taylor; +Cc: Eli Zaretskii, Yuan Fu, 60407 Hi Randy, I'm providing the updated patch - I've addressed your comments and also added Electric Pair mode settings (variable electric-indent-chars). Thanks for your feedback. Again, please let me know if the patch can be improved. The patch is below. commit c38df01b088c3fdc0b86340a230b7397b5c81317 Author: Evgeni Kolev <evgenysw@gmail.com> Date: Thu Dec 29 17:49:40 2022 +0200 Improve go-ts-mode Imenu, navigation and electric pair configuration The Imenu items are extended to support "Method", "Struct", "Interface", "Alias" and "Type". go-ts-mode is updated to use the Imenu facility added in commit b39dc7ab27a696a8607ab859aeff3c71509231f5. Variable electric-indent-chars is set in order to improve integration with Electric Pair mode. * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): Remove functions. (go-ts-mode--defun-name, go-ts-mode--interface-node-p) (go-ts-mode--struct-node-p, go-ts-mode--other-type-node-p) (go-ts-mode--alias-node-p): New functions. (go-ts-mode): Improve Imenu settings, navigation, add Electric Pair mode settings. diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 1d6a8a30db5..64e761d2f72 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -36,6 +36,7 @@ (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-start "treesit.c") (declare-function treesit-node-type "treesit.c") +(declare-function treesit-search-subtree "treesit.c") (defcustom go-ts-mode-indent-offset 4 "Number of spaces for each indentation step in `go-ts-mode'." @@ -173,44 +174,6 @@ go-ts-mode--font-lock-settings '((ERROR) @font-lock-warning-face)) "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index `(("Function" . ,func-index))) - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for `go-ts-mode--imenu'. -Find string representation for NODE and set marker, then recurse -the subtrees." - (let* ((ts-node (car node)) - (children (cdr node)) - (subtrees (mapcan #'go-ts-mode--imenu-1 - children)) - (name (when ts-node - (treesit-node-text - (pcase (treesit-node-type ts-node) - ("function_declaration" - (treesit-node-child-by-field-name ts-node "name")) - ("type_spec" - (treesit-node-child-by-field-name ts-node "name")))))) - (marker (when ts-node - (set-marker (make-marker) - (treesit-node-start ts-node))))) - (cond - ((or (null ts-node) (null name)) subtrees) - (subtrees - `((,name ,(cons name marker) ,@subtrees))) - (t - `((,name . ,marker)))))) - ;;;###autoload (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) @@ -228,14 +191,30 @@ go-ts-mode (setq-local comment-end "") (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + ;; Navigation. + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "function_declaration" + "type_declaration"))) + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) + ;; Imenu. - (setq-local imenu-create-index-function #'go-ts-mode--imenu) - (setq-local which-func-functions nil) + (setq-local treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Method" "\\`method_declaration\\'" nil nil) + ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil) + ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\`type_declaration\\'" go-ts-mode--other-type-node-p nil) + ("Alias" "\\`type_declaration\\'" go-ts-mode--alias-node-p nil))) ;; Indent. (setq-local indent-tabs-mode t treesit-simple-indent-rules go-ts-mode--indent-rules) + ;; Electric + (setq-local electric-indent-chars + (append "{}()" electric-indent-chars)) + ;; Font-lock. (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings) (setq-local treesit-font-lock-feature-list @@ -247,6 +226,54 @@ go-ts-mode (treesit-major-mode-setup))) +(defun go-ts-mode--defun-name (node) + "Return the defun name of NODE. +Return nil if there is no name or if NODE is not a defun node." + (pcase (treesit-node-type node) + ("function_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + node "name") + t)) + ("method_declaration" + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) + (type-node (treesit-search-subtree receiver-node "type_identifier")) + (name-node (treesit-node-child-by-field-name node "name"))) + (concat + "(" (treesit-node-text type-node) ")." + (treesit-node-text name-node)))) + ("type_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "name") + t)))) + +(defun go-ts-mode--interface-node-p (node) + "Return t if NODE is an interface." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "interface_type" nil nil 2))) + +(defun go-ts-mode--struct-node-p (node) + "Return t if NODE is a struct." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "struct_type" nil nil 2))) + +(defun go-ts-mode--alias-node-p (node) + "Return t if NODE is a type alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "type_alias" nil nil 1))) + +(defun go-ts-mode--other-type-node-p (node) + "Return t if NODE is a type, other than interface, struct or alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (not (go-ts-mode--interface-node-p node)) + (not (go-ts-mode--struct-node-p node)) + (not (go-ts-mode--alias-node-p node)))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table On Tue, Jan 3, 2023 at 4:31 PM Randy Taylor <dev@rjt.dev> wrote: > > On Tuesday, January 3rd, 2023 at 04:01, Evgeni Kolev <evgenysw@gmail.com> wrote: > > > > Hi Randy, thank you for your feedback! > > > > I'm providing an updated patch below. I tested with "type Quack int" > > and other cases such as: > > type MyInt = int > > type Option func(s string) > > type List[T any] struct { > > head, tail *element[T] > > } > > type Number interface { > > int64 | float64 > > } > > > > After experimenting, I decided to add additional Imenu categories: > > "Alias" and "Type". > > So the final list of newly added categories is "Method", "Struct", > > "Interface", "Alias" and "Type". > > Sounds good to me. > > It looks like the alias type MyInt = int shows up in both categories: Alias and Type. > It should probably belong just in the Alias category. > > > > > Structs and interfaces are technically a private case for "Type", but > > are put in their own Imenu category. > > Hence the "Type" category now holds all types except structs, > > interfaces and aliases (aliases have their own tree sitter type > > defined in Go's grammar.js). > > > > For reference, eglot's Imenu uses category "Class" instead of "Type". > > But I decided to not replicate this behavior - "Class" is not a widely > > used Go concept. > > However, I decided to replicate another eglot behaviour - prefixing > > the method names with the type of the receiver (for example, > > "(rect).area" for "func (r rect) area() float64..."). > > Great! I was going to suggest that but forgot. > > > > > I've also addressed the other comments. I'm a bit unsure how the git > > commit should be formatted - the part of the message which describes > > changed functions/files. > > > > Please let me know if the patch can be improved. The patch is below. > > Comments below. > > > > > commit a96e70052a79881ac666ab699ffd63ed916eaf83 > > Author: Evgeni Kolev evgenysw@gmail.com > > > > Date: Thu Dec 29 17:49:40 2022 +0200 > > > > Improve go-ts-mode Imenu > > Maybe this should also say "and add navigation support" (or something similar)? > > > > > The Imenu items are extended to support "Method", "Struct", > > "Interface", "Alias" and "Type". > > > > go-ts-mode is updated to use the Imenu facility added in commit > > b39dc7ab27a696a8607ab859aeff3c71509231f5. > > > > * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): > > Remove functions. > > (go-ts-mode--defun-name) (go-ts-mode--interface-node-p) > > I'm no commit format expert, but I think this can be (go-ts-mode--defun-name, go-ts-mode--interface-node-p) > Whenever it fits on a single line, you can combine them like that. Same for the line below. > > > (go-ts-mode--struct-node-p) (go-ts-mode--other-type-node-p) > > (go-ts-mode--alias-node-p): New functions. > > (go-ts-mode): Improve Imenu settings. > > I think the (go-ts-mode) part should mention that navigation support was added. > > > > > diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el > > index 1d6a8a30db5..d91b555e03e 100644 > > --- a/lisp/progmodes/go-ts-mode.el > > +++ b/lisp/progmodes/go-ts-mode.el > > @@ -173,44 +173,6 @@ go-ts-mode--font-lock-settings > > '((ERROR) @font-lock-warning-face)) > > "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index` (("Function" . ,func-index))) > > - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for` go-ts-mode--imenu'. > > -Find string representation for NODE and set marker, then recurse > > -the subtrees." > > - (let* ((ts-node (car node)) > > - (children (cdr node)) > > - (subtrees (mapcan #'go-ts-mode--imenu-1 > > - children)) > > - (name (when ts-node > > - (treesit-node-text > > - (pcase (treesit-node-type ts-node) > > - ("function_declaration" > > - (treesit-node-child-by-field-name ts-node "name")) > > - ("type_spec" > > - (treesit-node-child-by-field-name ts-node "name")))))) > > - (marker (when ts-node > > - (set-marker (make-marker) > > - (treesit-node-start ts-node))))) > > - (cond > > - ((or (null ts-node) (null name)) subtrees) > > - (subtrees > > - `((,name ,(cons name marker) ,@subtrees))) - (t -` ((,name . ,marker)))))) > > - > > ;;;###autoload > > (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) > > > > @@ -228,9 +190,21 @@ go-ts-mode > > (setq-local comment-end "") > > (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) > > > > + ;; Navigation. > > + (setq-local treesit-defun-type-regexp > > + (regexp-opt '("method_declaration" > > + "function_declaration" > > + "type_declaration"))) > > + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) > > + > > ;; Imenu. > > - (setq-local imenu-create-index-function #'go-ts-mode--imenu) > > - (setq-local which-func-functions nil) > > + (setq-local treesit-simple-imenu-settings > > + `(("Function" "\\\\`function_declaration\\'" nil nil) > > + ("Method" "\\`method_declaration\\\\'" nil nil) + ("Struct" "\\\\`type_declaration\\'" > > go-ts-mode--struct-node-p nil) > > + ("Interface" "\\`type_declaration\\\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\\\`type_declaration\\'" > > go-ts-mode--other-type-node-p nil) > > + ("Alias" "\\`type_declaration\\'" > > go-ts-mode--alias-node-p nil))) > > > > ;; Indent. > > (setq-local indent-tabs-mode t > > @@ -247,6 +221,53 @@ go-ts-mode > > > > (treesit-major-mode-setup))) > > > > +(defun go-ts-mode--defun-name (node) > > + "Return the defun name of NODE. > > +Return nil if there is no name or if NODE is not a defun node." > > + (pcase (treesit-node-type node) > > + ("function_declaration" > > + (treesit-node-text > > + (treesit-node-child-by-field-name > > + node "name") > > + t)) > > + ("method_declaration" > > + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) > > + (type-node (treesit-search-subtree receiver-node > > "type_identifier")) > > + (name-node (treesit-node-child-by-field-name node "name"))) > > + (concat > > + "(" (treesit-node-text type-node) ")." > > + (treesit-node-text name-node)))) > > + ("type_declaration" > > + (treesit-node-text > > + (treesit-node-child-by-field-name > > + (treesit-node-child node 0 t) "name") > > + t)))) > > + > > +(defun go-ts-mode--interface-node-p (node) > > + "Return t if NODE is an interface." > > + (and > > + (string-equal "type_declaration" (treesit-node-type node)) > > + (treesit-search-subtree node "interface_type" nil nil 2))) > > I think you need to add (declare-function treesit-search-subtree "treesit.c") after the last one at the top of the file. > > > + > > +(defun go-ts-mode--struct-node-p (node) > > + "Return t if NODE is a struct." > > + (and > > + (string-equal "type_declaration" (treesit-node-type node)) > > + (treesit-search-subtree node "struct_type" nil nil 2))) > > + > > +(defun go-ts-mode--alias-node-p (node) > > + "Return t if NODE is a type alias." > > + (and > > + (string-equal "type_declaration" (treesit-node-type node)) > > + (treesit-search-subtree node "type_alias" nil nil 1))) > > + > > +(defun go-ts-mode--other-type-node-p (node) > > + "Return t if NODE is a type, other than interface or struct." > > + (and > > + (string-equal "type_declaration" (treesit-node-type node)) > > + (not (go-ts-mode--interface-node-p node)) > > + (not (go-ts-mode--struct-node-p node)))) > > Here I guess we just need a (not alias) (and the docstring updated) to fix the issue mentioned above. > > > + > > ;; go.mod support. > > > > (defvar go-mod-ts-mode--syntax-table > > ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-05 7:24 ` Evgeni Kolev @ 2023-01-05 14:21 ` Randy Taylor 0 siblings, 0 replies; 14+ messages in thread From: Randy Taylor @ 2023-01-05 14:21 UTC (permalink / raw) To: Evgeni Kolev; +Cc: Eli Zaretskii, 60407, Yuan Fu On Thursday, January 5th, 2023 at 02:24, Evgeni Kolev <evgenysw@gmail.com> wrote: > > Hi Randy, > > I'm providing the updated patch - I've addressed your comments and > also added Electric Pair mode settings (variable > electric-indent-chars). > > Thanks for your feedback. Again, please let me know if the patch can > be improved. I can't speak to the electric stuff, but everything else looks good to me! Thanks for working on this. Yuan, feel free to apply if it looks good to you. ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-01 9:07 ` Eli Zaretskii 2023-01-01 13:05 ` Evgeni Kolev @ 2023-01-01 13:08 ` Randy Taylor 1 sibling, 0 replies; 14+ messages in thread From: Randy Taylor @ 2023-01-01 13:08 UTC (permalink / raw) To: Eli Zaretskii; +Cc: Evgeni Kolev, 60407, Yuan Fu On Sunday, January 1st, 2023 at 04:07, Eli Zaretskii <eliz@gnu.org> wrote: > > > From: Evgeni Kolev evgenysw@gmail.com > > > Date: Thu, 29 Dec 2022 18:05:49 +0200 > > > > This patch updates go-ts-mode to use Imenu facility added in > > https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-29&id=b39dc7ab27a696a8607ab859aeff3c71509231f5 > > > > The Imenu items are extended to support "Method", in addition to > > "Function" and "Type". > > > > The current Imenu approach uses "type_spec" to identify "Type" which > > acts as a catch-all for many Go constructs, for example struct and > > interface definitions. This catch-all approach is not optimal because > > structs and interfaces are put in the same "Type" bucket. In a > > follow-up patch I'll try to change the approach and have separate > > "Interface" and "Struct" types. > > > > The patch is below. > > > Randy, Yuan, are you looking into this? Sorry, been preoccupied recently. It's on my radar and I'll take a look and test it out later today. ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2022-12-29 16:05 bug#60407: [PATCH] Update go-ts-mode to use Imenu facility Evgeni Kolev 2023-01-01 9:07 ` Eli Zaretskii @ 2023-01-08 0:20 ` Yuan Fu 2023-01-08 8:10 ` Evgeni Kolev 2023-01-09 0:35 ` Yuan Fu 2 siblings, 1 reply; 14+ messages in thread From: Yuan Fu @ 2023-01-08 0:20 UTC (permalink / raw) To: Randy Taylor; +Cc: evgenysw, Eli Zaretskii, 60407 Randy Taylor <dev@rjt.dev> writes: > On Thursday, January 5th, 2023 at 02:24, Evgeni Kolev <evgenysw@gmail.com> wrote: >> >> Hi Randy, >> >> I'm providing the updated patch - I've addressed your comments and >> also added Electric Pair mode settings (variable >> electric-indent-chars). >> >> Thanks for your feedback. Again, please let me know if the patch can >> be improved. > > I can't speak to the electric stuff, but everything else looks good to me! > Thanks for working on this. > > Yuan, feel free to apply if it looks good to you. Ok! However, Evgeni, could you resend your patch as a attachment please? My ad-hoc setup couldn’t apply the inline patch directly :-) Yuan ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-08 0:20 ` Yuan Fu @ 2023-01-08 8:10 ` Evgeni Kolev 2023-01-08 10:59 ` Eli Zaretskii 0 siblings, 1 reply; 14+ messages in thread From: Evgeni Kolev @ 2023-01-08 8:10 UTC (permalink / raw) To: Yuan Fu; +Cc: Randy Taylor, Eli Zaretskii, 60407 [-- Attachment #1: Type: text/plain, Size: 1428 bytes --] Hi Yuan, sure, the .patch is attached. A side question - does it make sense to extend go-ts-mode with interactive functions? For example a function (go-ts-mode-docstring) which adds a docstring for the current type: with Go code: func sum(a, b int) int {...} the function would add a comment above the func: // sum func sum(a, b int) int {...} This is something I've implemented for myself, I'm wondering if it makes sense to contribute it to go-ts-mode. Or should I first discuss this in the devel mail list? Or maybe send another patch and have the discussion there? On Sun, Jan 8, 2023 at 2:20 AM Yuan Fu <casouri@gmail.com> wrote: > > > Randy Taylor <dev@rjt.dev> writes: > > > On Thursday, January 5th, 2023 at 02:24, Evgeni Kolev <evgenysw@gmail.com> wrote: > >> > >> Hi Randy, > >> > >> I'm providing the updated patch - I've addressed your comments and > >> also added Electric Pair mode settings (variable > >> electric-indent-chars). > >> > >> Thanks for your feedback. Again, please let me know if the patch can > >> be improved. > > > > I can't speak to the electric stuff, but everything else looks good to me! > > Thanks for working on this. > > > > Yuan, feel free to apply if it looks good to you. > > Ok! However, Evgeni, could you resend your patch as a attachment please? > My ad-hoc setup couldn’t apply the inline patch directly :-) > > Yuan [-- Attachment #2: 0001-Improve-go-ts-mode-Imenu-navigation-and-electric-pai.patch --] [-- Type: application/octet-stream, Size: 6671 bytes --] From dd618f10ec750e363ac2f7c89433dd2f8a647c31 Mon Sep 17 00:00:00 2001 From: Evgeni Kolev <evgenysw@gmail.com> Date: Thu, 29 Dec 2022 17:49:40 +0200 Subject: [PATCH] Improve go-ts-mode Imenu, navigation and electric pair configuration The Imenu items are extended to support "Method", "Struct", "Interface", "Alias" and "Type". go-ts-mode is updated to use the Imenu facility added in commit b39dc7ab27a696a8607ab859aeff3c71509231f5. Variable electric-indent-chars is set in order to improve integration with Electric Pair mode. * lisp/progmodes/go-ts-mode.el (go-ts-mode--imenu-1) (go-ts-mode--imenu): Remove functions. (go-ts-mode--defun-name, go-ts-mode--interface-node-p) (go-ts-mode--struct-node-p, go-ts-mode--other-type-node-p) (go-ts-mode--alias-node-p): New functions. (go-ts-mode): Improve Imenu settings, navigation, add Electric Pair mode settings. --- lisp/progmodes/go-ts-mode.el | 107 ++++++++++++++++++++++------------- 1 file changed, 67 insertions(+), 40 deletions(-) diff --git a/lisp/progmodes/go-ts-mode.el b/lisp/progmodes/go-ts-mode.el index 1d6a8a30db5..64e761d2f72 100644 --- a/lisp/progmodes/go-ts-mode.el +++ b/lisp/progmodes/go-ts-mode.el @@ -36,6 +36,7 @@ (declare-function treesit-node-child-by-field-name "treesit.c") (declare-function treesit-node-start "treesit.c") (declare-function treesit-node-type "treesit.c") +(declare-function treesit-search-subtree "treesit.c") (defcustom go-ts-mode-indent-offset 4 "Number of spaces for each indentation step in `go-ts-mode'." @@ -173,44 +174,6 @@ go-ts-mode--font-lock-settings '((ERROR) @font-lock-warning-face)) "Tree-sitter font-lock settings for `go-ts-mode'.") -(defun go-ts-mode--imenu () - "Return Imenu alist for the current buffer." - (let* ((node (treesit-buffer-root-node)) - (func-tree (treesit-induce-sparse-tree - node "function_declaration" nil 1000)) - (type-tree (treesit-induce-sparse-tree - node "type_spec" nil 1000)) - (func-index (go-ts-mode--imenu-1 func-tree)) - (type-index (go-ts-mode--imenu-1 type-tree))) - (append - (when func-index `(("Function" . ,func-index))) - (when type-index `(("Type" . ,type-index)))))) - -(defun go-ts-mode--imenu-1 (node) - "Helper for `go-ts-mode--imenu'. -Find string representation for NODE and set marker, then recurse -the subtrees." - (let* ((ts-node (car node)) - (children (cdr node)) - (subtrees (mapcan #'go-ts-mode--imenu-1 - children)) - (name (when ts-node - (treesit-node-text - (pcase (treesit-node-type ts-node) - ("function_declaration" - (treesit-node-child-by-field-name ts-node "name")) - ("type_spec" - (treesit-node-child-by-field-name ts-node "name")))))) - (marker (when ts-node - (set-marker (make-marker) - (treesit-node-start ts-node))))) - (cond - ((or (null ts-node) (null name)) subtrees) - (subtrees - `((,name ,(cons name marker) ,@subtrees))) - (t - `((,name . ,marker)))))) - ;;;###autoload (add-to-list 'auto-mode-alist '("\\.go\\'" . go-ts-mode)) @@ -228,14 +191,30 @@ go-ts-mode (setq-local comment-end "") (setq-local comment-start-skip (rx "//" (* (syntax whitespace)))) + ;; Navigation. + (setq-local treesit-defun-type-regexp + (regexp-opt '("method_declaration" + "function_declaration" + "type_declaration"))) + (setq-local treesit-defun-name-function #'go-ts-mode--defun-name) + ;; Imenu. - (setq-local imenu-create-index-function #'go-ts-mode--imenu) - (setq-local which-func-functions nil) + (setq-local treesit-simple-imenu-settings + `(("Function" "\\`function_declaration\\'" nil nil) + ("Method" "\\`method_declaration\\'" nil nil) + ("Struct" "\\`type_declaration\\'" go-ts-mode--struct-node-p nil) + ("Interface" "\\`type_declaration\\'" go-ts-mode--interface-node-p nil) + ("Type" "\\`type_declaration\\'" go-ts-mode--other-type-node-p nil) + ("Alias" "\\`type_declaration\\'" go-ts-mode--alias-node-p nil))) ;; Indent. (setq-local indent-tabs-mode t treesit-simple-indent-rules go-ts-mode--indent-rules) + ;; Electric + (setq-local electric-indent-chars + (append "{}()" electric-indent-chars)) + ;; Font-lock. (setq-local treesit-font-lock-settings go-ts-mode--font-lock-settings) (setq-local treesit-font-lock-feature-list @@ -247,6 +226,54 @@ go-ts-mode (treesit-major-mode-setup))) +(defun go-ts-mode--defun-name (node) + "Return the defun name of NODE. +Return nil if there is no name or if NODE is not a defun node." + (pcase (treesit-node-type node) + ("function_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + node "name") + t)) + ("method_declaration" + (let* ((receiver-node (treesit-node-child-by-field-name node "receiver")) + (type-node (treesit-search-subtree receiver-node "type_identifier")) + (name-node (treesit-node-child-by-field-name node "name"))) + (concat + "(" (treesit-node-text type-node) ")." + (treesit-node-text name-node)))) + ("type_declaration" + (treesit-node-text + (treesit-node-child-by-field-name + (treesit-node-child node 0 t) "name") + t)))) + +(defun go-ts-mode--interface-node-p (node) + "Return t if NODE is an interface." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "interface_type" nil nil 2))) + +(defun go-ts-mode--struct-node-p (node) + "Return t if NODE is a struct." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "struct_type" nil nil 2))) + +(defun go-ts-mode--alias-node-p (node) + "Return t if NODE is a type alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (treesit-search-subtree node "type_alias" nil nil 1))) + +(defun go-ts-mode--other-type-node-p (node) + "Return t if NODE is a type, other than interface, struct or alias." + (and + (string-equal "type_declaration" (treesit-node-type node)) + (not (go-ts-mode--interface-node-p node)) + (not (go-ts-mode--struct-node-p node)) + (not (go-ts-mode--alias-node-p node)))) + ;; go.mod support. (defvar go-mod-ts-mode--syntax-table -- 2.30.2 ^ permalink raw reply related [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2023-01-08 8:10 ` Evgeni Kolev @ 2023-01-08 10:59 ` Eli Zaretskii 0 siblings, 0 replies; 14+ messages in thread From: Eli Zaretskii @ 2023-01-08 10:59 UTC (permalink / raw) To: Evgeni Kolev; +Cc: dev, casouri, 60407 > From: Evgeni Kolev <evgenysw@gmail.com> > Date: Sun, 8 Jan 2023 10:10:33 +0200 > Cc: Randy Taylor <dev@rjt.dev>, Eli Zaretskii <eliz@gnu.org>, 60407@debbugs.gnu.org > > A side question - does it make sense to extend go-ts-mode with > interactive functions? > > For example a function (go-ts-mode-docstring) which adds a docstring > for the current type: > with Go code: > func sum(a, b int) int {...} > the function would add a comment above the func: > // sum > func sum(a, b int) int {...} > > This is something I've implemented for myself, I'm wondering if it > makes sense to contribute it to go-ts-mode. It makes sense, but it will have to wait until Emacs 30. The release branch is frozen, and no new features are accepted. > Or should I first discuss this in the devel mail list? Or maybe send > another patch and have the discussion there? Either one would be good. Thanks. ^ permalink raw reply [flat|nested] 14+ messages in thread
* bug#60407: [PATCH] Update go-ts-mode to use Imenu facility 2022-12-29 16:05 bug#60407: [PATCH] Update go-ts-mode to use Imenu facility Evgeni Kolev 2023-01-01 9:07 ` Eli Zaretskii 2023-01-08 0:20 ` Yuan Fu @ 2023-01-09 0:35 ` Yuan Fu 2 siblings, 0 replies; 14+ messages in thread From: Yuan Fu @ 2023-01-09 0:35 UTC (permalink / raw) To: evgenysw; +Cc: 60407-done Evgeni Kolev <evgenysw@gmail.com> writes: > Hi Yuan, sure, the .patch is attached. Thanks. I applied the patch. Yuan ^ permalink raw reply [flat|nested] 14+ messages in thread
end of thread, other threads:[~2023-01-09 0:35 UTC | newest] Thread overview: 14+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-12-29 16:05 bug#60407: [PATCH] Update go-ts-mode to use Imenu facility Evgeni Kolev 2023-01-01 9:07 ` Eli Zaretskii 2023-01-01 13:05 ` Evgeni Kolev 2023-01-01 17:08 ` Evgeni Kolev 2023-01-01 22:31 ` Randy Taylor 2023-01-03 9:01 ` Evgeni Kolev 2023-01-03 14:30 ` Randy Taylor 2023-01-05 7:24 ` Evgeni Kolev 2023-01-05 14:21 ` Randy Taylor 2023-01-01 13:08 ` Randy Taylor 2023-01-08 0:20 ` Yuan Fu 2023-01-08 8:10 ` Evgeni Kolev 2023-01-08 10:59 ` Eli Zaretskii 2023-01-09 0:35 ` Yuan Fu
Code repositories for project(s) associated with this public inbox https://git.savannah.gnu.org/cgit/emacs.git This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).