unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
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





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