From: Theodor Thornhill via "Bug reports for GNU Emacs, the Swiss army knife of text editors" <bug-gnu-emacs@gnu.org>
To: evgenysw@gmail.com, 61368@debbugs.gnu.org
Cc: Randy Taylor <dev@rjt.dev>
Subject: bug#61368: [PATCH] Extend go-ts-mode with support for pre-filling return statements
Date: Wed, 08 Feb 2023 20:20:27 +0100 [thread overview]
Message-ID: <87o7q46k1w.fsf@thornhill.no> (raw)
In-Reply-To: <CAMCrgaUgMx9+0Q8f_cezZ0TW_-u=mdeHf=TL=qw9wbhiS-nJ9w@mail.gmail.com>
Evgeni Kolev <evgenysw@gmail.com> writes:
> [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
> })
> }
> ```
Cool!
>
> 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.
>
How about using tempo or skeleton as fallbacks when yasnippet isn't
installed?
> 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?
>
Personally I think this should be a contrib to gopls as a code action so
that others can benefit from it. Is upstreaming it to gopls too hard?
Theo
prev parent reply other threads:[~2023-02-08 19:20 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87o7q46k1w.fsf@thornhill.no \
--to=bug-gnu-emacs@gnu.org \
--cc=61368@debbugs.gnu.org \
--cc=dev@rjt.dev \
--cc=evgenysw@gmail.com \
--cc=theo@thornhill.no \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).