Subject: bug#61368: [PATCH] Extend go-ts-mode with support for pre-filling return statements

From: Evgeni Kolev <[email-masked]>
Date: Thu, 9 Feb 2023 13:47:01 +0200

On Wed, Feb 8, 2023 at 9:20 PM Theodor Thornhill <[email-masked]> wrote:
>
> Evgeni Kolev <[email-masked]> writes:
>
> >
> > 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?

I've never used either of these packages. Is there a consensus which
one is preferred for major modes to use?

>
> 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?
>

Great suggestion! I did a quick research and this seems to already be
implemented in gopls here:
https://github.com/golang/tools/blob/master/gopls/internal/lsp/source/completion/statements.go#L179

To use it you have to enable "usePlaceholders", reference:
https://github.com/golang/tools/blob/master/gopls/doc/settings.md

Do you think it makes sense go-ts-mode to also have its own
implementation? I think it does - similar to how both gopls (eglot)
and tree sitter provide Imenu candidates. I personally use tree
sitter's Imenu (setq eglot-stay-out-of '(imenu)) because I find it
advantageous to avoid the RPC call to an external process.

Also having a tree sitter implementation is more flexible. For
example, I'm planning to have multiple yasnippet snippets for
different scenarios (wrap the error, don't wrap, return a new error,
etc.). The gopls implementation is ridgid - it only works if there's
an "err" variable in scope, and the trigger is one of these three "if
e", "if er" and "if err".

On Wed, Feb 8, 2023 at 6:30 PM Eli Zaretskii <[email-masked]> wrote:
> > 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.
>
> Instead of a command bound to a special key sequences, would it
> perhaps make more sense to add some kind of "electric" behavior to
> "normal" keys?  Like perhaps typing RET after inserting "return" would
> add the "context-aware return statement"?  Then the user could turn on
> the electric behavior with some minor mode, and get this behavior,
> while avoiding the need to dedicate a key sequence.
>
> WDYT?

Makes sense. I am familiar with electric-pair-mode. I see that it adds
a hook in post-self-insert-hook. Is your suggestion to do something
like this:
- add hook in post-self-insert-hook
- in the hook check if RET is typed after an "return"
- if yes, replace the "return" with the "context-aware return
statement", possibly using (yas-expand-snippet)

I'm wondering what customization options would make sense for users -
changing the electric trigger from "return" RET to "ret" RET for
example.

Is there another major mode which can be used as an example for such
electric behavior?