Skip to content

x/tools/gopls: provide a way to run ExecuteCommand features in one step #40438

Closed
@leitzler

Description

@leitzler

What version of Go are you using (go version)?

golang.org/x/tools v0.0.0-20200721032237-77f530d86f9a
golang.org/x/tools/gopls v0.0.0-20200721032237-77f530d86f9a

I was adding fillstruct support to govim and they way gopls currently works is that it require a CodeAction/ExecuteCommand/ApplyEdit dance.

From a user point of view I see fillstruct as a direct request, initiated when the user already have the cursor placed on a non-filled struct identifier and the sole intention is to fill it.

It would be nice to be able to call ExecuteCommand from the client w/o a CodeAction request in before, but as discussed on Slack the different commands (and their arguments) aren't stable enough to be made public.
Example of a fillstruct command as returned by CodeAction:

Command:     &protocol.Command{
    Title:     "Fill foo with default values",
    Command:   "fill_struct",
    Arguments: {
        "{\"uri\":\"file:///private/var/folders/xm/ls208xd174v95pgd20rn_qbh0000gn/T/tmp.lmXRD9mP/main.go\",\"range\":{\"start\":{\"line\":7,\"character\":6},\"end\":{\"line\":7,\"character\":6}}}",
    },
},

As long as there is only one single (fillstruct) Command in the response, govim can automatically do another roundtrip and call ExecuteCommand with that Command. But if there are more than one Command in the CodaAction response (or the command isn't a fillstruct) there is currently no good way for the client to tell them apart.

Neither Command name (e.g. "fill_struct") or Arguments are specified anywhere so the client cannot know if/which command that belong to the request. Title is a dynamic string that contain the struct identifier. Using that field would require string matching (and unique struct identifiers on each line).

AFAIK other commands, such as "Extract variable" or "Extract function", are falls into the same category of user-invoked commands with a clear intent.

From my point of view gopls needs the following to be able to provide one step commands (I could obviously have missed other/better ways).

  • Use explicit kinds for all CodeActions with Commands, like refactor.rewrite.fillstruct instead of just the base kind refactor.rewrite so that it is possible to request a single kind of code action commands.
  • Allow a more narrow range as part of the CodeAction request (see CL244519). fillstruct operates on the whole line regardless of range specified in the CodeAction parameters.

Metadata

Metadata

Assignees

Labels

FeatureRequestIssues asking for a new feature that does not need a proposal.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions