Skip to content

Wingman: Using the completion system for case analysis #2437

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kalhauge opened this issue Dec 3, 2021 · 7 comments
Closed

Wingman: Using the completion system for case analysis #2437

kalhauge opened this issue Dec 3, 2021 · 7 comments
Labels

Comments

@kalhauge
Copy link

kalhauge commented Dec 3, 2021

Is your feature request related to a problem? Please describe.

When I write code I often write it like this:

foldMaybe :: Monoid m => Maybe m -> m
foldMaybe m = case m of 
   -- hmm.. what was the cases for Maybe again...

Right now I have to,

  1. stop what I'm doing,
  2. click on the code lens hint,
  3. and apply the change,
  4. navigate to the first _ and start writing.

Describe the solution you'd like

It would be really nice if we could somehow "TAB" (pun intended) into the lsp completion/snippet system,
and when I have written the of I can tap complete and be presented with a case expansion,
(and possibly a 'hylo'-morphic case expansion and a monadic case expansion):

foldMaybe :: Monoid m => Maybe m -> m
foldMaybe m = case m of<TAB>(choose case)
   Just a -> _
   Nothing -> _

mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe  fn m  = case m of<TAB>(choose hylo)
   Just a -> Just _
   Nothing -> Nothing

mapMaybeM :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
mapMaybeM m = case m of<TAB>(choose "do" hylo)
   Just a -> do 
    pure $ Just _
   Nothing -> do 
    pure $ Nothing

This suggestion is only for the case analysis part, it might however also work for refinements. If you
are on a "_" and press tab, it could suggest a refined solution if it finds one in less than 0.x seconds, suggest it, otherwise it might suggest one of the other transformations.

Describe alternatives you've considered

Wingman works great as is, but this would really be a "killer" feature.

Additional context

There seem to be some kind of support for snippets in the LSP protocol, but I don't know how well it is integrated in the different editors (and in the haskell-language-server).

@pepeiborra
Copy link
Collaborator

You could create key bindings to trigger code lenses, depending on your editor, if that's what bothers you.

But I agree that having a Wingman powered completion provider would be awesome.

@pepeiborra
Copy link
Collaborator

Would you be interested in contributing a PR? I'm sure @isovector could provide some starting tips

@kalhauge
Copy link
Author

kalhauge commented Dec 3, 2021

@pepeiborra I do have some time over the Christmas break, but I have no Idea about where to start. I'm pretty familiar to Haskell, but new to both the HLS code-base and to LSP.

@isovector
Copy link
Collaborator

isovector commented Dec 3, 2021

This sounds like a great idea. It looks like we can use the command? property in CompletionItem to connect to. Might be as easy as running the code lens action?

@kalhauge
Copy link
Author

kalhauge commented Dec 3, 2021

It seems like there is an example setup (sadly, not using the _comand option) use in plugins/hls-pragmas-plugin/src/Ide/Plugin/Pragmas.hs:L212 which might be usefull?

@michaelpj
Copy link
Collaborator

The ideal way would be to actually return the text to be inserted as part of the completion item edit, since then you could indeed send it as a snippet, which would potentially give a nicer UX. I guess computing the edit is expensive, but since we'd presumably only do this completion after an of token, it shouldn't be too hard to mostly avoid doing the work?

@kalhauge
Copy link
Author

kalhauge commented Dec 6, 2021

The ideal way would be to actually return the text to be inserted as part of the completion item edit, since then you could indeed send it as a snippet, which would potentially give a nicer UX. I guess computing the edit is expensive, but since we'd presumably only do this completion after an of token, it shouldn't be too hard to mostly avoid doing the work?

This is exactly something I think would be really useful. Also I think we could expand it to also work for _. Seeing the snippet before applying it, could make the user more willing to experiment with different tactics?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants