unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#61368: [PATCH] Extend go-ts-mode with support for pre-filling return statements
@ 2023-02-08 15:27 Evgeni Kolev
  2023-02-08 16:30 ` Eli Zaretskii
  2023-02-08 19:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
  0 siblings, 2 replies; 14+ messages in thread
From: Evgeni Kolev @ 2023-02-08 15:27 UTC (permalink / raw)
  To: 61368; +Cc: Randy Taylor, Theodor Thornhill

[-- Attachment #1: Type: text/plain, Size: 2804 bytes --]

[CC Randy, author of go-ts-mode, Theo, who asked to keep the patches coming :)]

This is a patch which adds support to go-ts-mode to insert
context-aware return statements for the current function. The return
statements are pre-filled with the Go zero values of the output
parameters.

For example, all these return statements are inserted by M-x
go-ts-mode-insert-return:

```
func f() (x, y, z int) {
    return 0, 0, 0
}

func exotic() (bool, int, myStruct, *int, chan bool, error) {
    return false, 0, myStruct{}, nil, nil, err
}

func closure(numbers []int) {
    sort.Slice(numbers, func(i, j int) bool {
        return false
    })
}
```

The command go-ts-mode-insert-return is experimentally bound to a key
C-c C-r ("r" as return statement). It's a user error to run C-c C-r
outside of a function body.

Customization: when the output params contain "error" the pre-filled
text is "err". A customization variable is added to allow the user to
pick a different value, for example they might pick `fmt.Errorf("...:
%w", err)` which will result in error wrapping:
```
func f() (int, error) {
    return 0, fmt.Errorf("...: %w", err)
}
```

Personally, I'll use yasnippet instead of C-c C-r. Something like this:
```
 # -*- mode: snippet -*-
 # name: ret
 # key: ret
 # type: command
 # --

 (let ((go-ts-mode-error-zero-value "${1:fmt.Errorf(\"${2:format}:
%w\", err)}"))
   (yas-expand-snippet (go-ts-mode-return)))
```

I'm open to suggestions about how to best expose this functionality to
the user. I think a snippet makes the most sense, but there's no
standard way for major modes to expose snippets as far as I'm aware.
It's possible to tweak C-c C-r to call (yas-expand-snippet) if
available, otherwise call (insert). In general, I don't feel strong
about the C-c C-r key binding, but I didn't have a better idea.

Known bug: this example does not work, fails with error "Unknown Go
type "[int]int"":
```
func notOk() (int, map[int]int) {
}
```
The root cause is an issue with the tree-sitter-go parser. The bug has
been reported here
https://github.com/tree-sitter/tree-sitter-go/issues/107

Known limitation: unfamiliar types are assumed to be structs. This
assumption does not work for aliased types. For example:
```
type MyInt = int

func alias() MyInt {
    return MyInt{}
}
```
Above the correct return statement is "return MyInt(0)". My assumption
is that type aliases of primitive types are rare in Go codebases. In
these rare cases, the user is expected to replace "MyInt{}" with
"MyInt(0)", or not use C-c C-r at all.

Inspired by: this emacs conf talk "08:21 Intelligent templates"
https://emacsconf.org/2022/talks/treesitter/

Feedback is more than welcome! In particular:
- how to best expose the functionality - key binding, snippet (how
exactly?), something else?

Evgeni

[-- Attachment #2: 0001-Extend-go-ts-mode-with-support-for-pre-filling-retur.patch --]
[-- Type: application/x-patch, Size: 6378 bytes --]

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2024-01-15 11:40 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-08 15:27 bug#61368: [PATCH] Extend go-ts-mode with support for pre-filling return statements Evgeni Kolev
2023-02-08 16:30 ` Eli Zaretskii
2023-02-09 11:47   ` Evgeni Kolev
2023-02-09 13:39     ` Eli Zaretskii
2023-02-18 11:46       ` Evgeni Kolev
2023-02-18 12:14         ` João Távora
2023-02-20  8:54           ` Evgeni Kolev
2023-02-20 12:55             ` Eli Zaretskii
2023-02-22 14:36               ` Evgeni Kolev
2024-01-10 22:43                 ` Stefan Kangas
2024-01-15  8:21                   ` Evgeni Kolev
2024-01-15  8:39                     ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors
2024-01-15 11:40                       ` João Távora
2023-02-08 19:20 ` Theodor Thornhill via Bug reports for GNU Emacs, the Swiss army knife of text editors

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).