golang / vscode-go

Go extension for Visual Studio Code
https://marketplace.visualstudio.com/items?itemName=golang.Go
Other
3.85k stars 736 forks source link

Add Package/Interface Dropdowns to Generate Interface Stubs Command #1547

Open madxmike opened 3 years ago

madxmike commented 3 years ago

Is your feature request related to a problem? Please describe. One of the features that I use the most in this extension is the "Generate Interface Stubs" command. It's great, but one of my main gripes with the feature is having to actually remember both the package and name of the interface I am wanting to implement. Often I'll forget mid-typing, quit the prompt, go reference what I am trying to implement, return to my file, and then do the command again. Even more often I'll just mistype and nothing will be generated.

Describe the solution you'd like It would be great to have a drop down list appear when you get to the interface name of the command. For instance:

When you type f *File and then space a drop down will appear with a list of packages, much like the list found in the "Add Import" command. You can then type the package name or choose from the list. After the dot, a list of all the interfaces found in that package will appear. You can then type the interface name or choose from the list.

Describe alternatives you've considered Another idea would just be to check if the interface exists after every keystroke, and then give a warning if it does not. I think that this would feel bad since the extension would flash a warning to you every time you type.

Additional context Example package selection Example package selection Example interface selection Example interface selection

findleyr commented 3 years ago

Hi, thanks for the suggestion.

This makes sense, though unlikely to be prioritized soon (the team is busy working on debugging and gopls). Looking at the available APIs I think we'd have to switch from an inputBox to quickPick, but it could be doable.

CC @hyangah @suzmue for their thoughts. Perhaps this could be an opportunity for external contribution.

hyangah commented 3 years ago

That's a bit unusual use case of quickPick or inputBox. I am guessing it requires some creativity on top of what vscode api offers by default. If any of you know reference or example to combine quickPick/inputBox + completion, please update this issue. Alternative is to have separate quickPicks for the first (the receiver type) and the second (the interface type) args.

Another question is where to get the candidate interface list. Obvious choice is gopls. In Go, a type can implement any interface type without explicitly importing the package where the interface is defined. In theory, the list can be infinite but we will need to come up with a reasonable heuristic.

findleyr commented 3 years ago

@hyangah FWIW my comment was based on https://github.com/microsoft/vscode/issues/426.

Gopls could definitely provide the candidate list. I think the hardest part of implementing this would be figuring out if the desired UI is possible.

findleyr commented 3 years ago

This feature could be useful, but we won't have time to work on it anytime soon. It mostly needs some UI research to see if there is a clean way to implement completion callbacks for dialog boxes. If someone could figure that out, I could add a custom command to gopls to populate the completion data.

Marking this as help-wanted as the UI research should be mostly self-contained.

day-dreams commented 3 years ago

https://marketplace.visualstudio.com/items?itemName=kakaxi.autoimpl

i just implement an extension for myself. hope it is useful for you too. usage

hyangah commented 3 years ago

@day-dreams The use of snippet (and placeholders) is smart and seems to work pretty nice. Do you mind contributing to this extension? It looks like the existing code is in https://github.com/golang/vscode-go/blob/master/src/goImpl.ts - and from the look this extension-specific logic is only to check whether impl is installed or not.

day-dreams commented 3 years ago

@hyangah of course, i would like to help imporve this extesion . gonna make a pr request soon

day-dreams commented 3 years ago

@day-dreams The use of snippet (and placeholders) is smart and seems to work pretty nice. Do you mind contributing to this extension? It looks like the existing code is in https://github.com/golang/vscode-go/blob/master/src/goImpl.ts - and from the look this extension-specific logic is only to check whether impl is installed or not.

made a pr request, hope to be merged. #1592

madxmike commented 3 years ago

Wow that looks great! I love that it does a multi-cursor edit for the receiver name. Seems much more intuitive and smooth than the current ui.

gopherbot commented 3 years ago

Change https://golang.org/cl/330850 mentions this issue: src/goImpl: improve goimpl implememtations (#1547)

hyangah commented 3 years ago

@day-dreams Thanks for the PR! I was playing with it and it seems like we need to sort out a couple of issues related to the use of the workspace symbol provider currently.

day-dreams commented 3 years ago

@day-dreams Thanks for the PR! I was playing with it and it seems like we need to sort out a couple of issues related to the use of the workspace symbol provider currently.

  • workspace symbol results from gopls currently include ambiguous results - see x/tools/gopls: spurious workspace symbol items go#46997
  • the PR first retrieves the workspace symbol list and then filters only "Interface" type symbols out of the list. Since gopls returns only the first K matching items, that means, after filtering, it's possible only a small number or even zero of Interface types are left - which may not include what users want. I think a better strategy is to implement a specialized command on the language server side, which returns only the interface types. That way, it may be more efficient and may include the interesting interface types in the list. cc gopls-devs for advice: @stamblerre @findleyr
  • we may need a fallback mechanism in case the candidate list has nothing matching - maybe a fake item that triggers the old logic. That can be done in a separate, follow up change though if it becomes a problem for many users.

it seems this feature needs more internal supports。 before vscode-go implements this feature, i will continue to use my extension. https://marketplace.visualstudio.com/items?itemName=kakaxi.autoimpl

hope you can support this soon :)

madxmike commented 3 years ago

Now that x/tools/gopls: spurious workspace symbol items go#46997 has been merged, is there any update on the status of this? This is still something I would really love to see as baseline in the extension,

hyangah commented 2 years ago

@day-dreams Can you please take a look at the diff I made from your PR so we can include it in the next release? Thanks again!

https://go-review.googlesource.com/c/vscode-go/+/330850/4..7/src/goImpl.ts

madxmike commented 2 years ago

I finally got around to working in go again, and decided to try and finish this feature.

I had saw the work done in https://github.com/golang/go/issues/37537 a few weeks ago. I think it would be best to leverage that work. I'm not sure we can utilize the snippet approach demonstrated above with the current gopls work since we need the concrete type info.

I made a quick poc for the picker using my original idea above to grab both the concrete and interface type's symbol info. I'm working on integrating a gopls command into the work above, but just wanted to show a quick gif of the picker for thoughts.

https://user-images.githubusercontent.com/2898444/172093577-250bdf3d-a221-4ede-a1e9-c11e377e83ab.mp4

One thing the gif doesnt show is that the struct quick pick is prefilled with the cursor's current selection if its available. I played around with it and it felt natural to me, but I'm not sure if everyone would like that functionality.