From a0cf054a4555933c163d9bff1b5395fa6de484ac Mon Sep 17 00:00:00 2001 From: Suzy Mueller Date: Wed, 14 Aug 2019 15:24:21 -0400 Subject: [PATCH] internal/lsp: initialize CodeActionProvider with supported actions Send the code action kinds that we support, if codeActionLiteralSupport is specified. Editors may use the CodeActionKinds that we support to determine UI layout for example. Change-Id: Iee368aa02c26f4395bb2894593ef38d84d3283b7 Reviewed-on: https://go-review.googlesource.com/c/tools/+/191620 Run-TryBot: Suzy Mueller TryBot-Result: Gobot Gobot Reviewed-by: Rebecca Stambler --- internal/lsp/code_action.go | 19 +++++++++++++++++++ internal/lsp/general.go | 15 ++++++++++++++- internal/lsp/protocol/tsprotocol.go | 2 +- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/internal/lsp/code_action.go b/internal/lsp/code_action.go index 2c6f065624..6b61894ace 100644 --- a/internal/lsp/code_action.go +++ b/internal/lsp/code_action.go @@ -7,6 +7,7 @@ package lsp import ( "context" "fmt" + "sort" "strings" "golang.org/x/tools/internal/imports" @@ -18,6 +19,24 @@ import ( errors "golang.org/x/xerrors" ) +func (s *Server) getSupportedCodeActions() []protocol.CodeActionKind { + allCodeActionKinds := make(map[protocol.CodeActionKind]struct{}) + for _, kinds := range s.supportedCodeActions { + for kind := range kinds { + allCodeActionKinds[kind] = struct{}{} + } + } + + var result []protocol.CodeActionKind + for kind := range allCodeActionKinds { + result = append(result, kind) + } + sort.Slice(result, func(i, j int) bool { + return result[i] < result[j] + }) + return result +} + func (s *Server) codeAction(ctx context.Context, params *protocol.CodeActionParams) ([]protocol.CodeAction, error) { uri := span.NewURI(params.TextDocument.URI) view := s.session.ViewOf(uri) diff --git a/internal/lsp/general.go b/internal/lsp/general.go index b946abe5d4..51f9f438ed 100644 --- a/internal/lsp/general.go +++ b/internal/lsp/general.go @@ -77,9 +77,22 @@ func (s *Server) initialize(ctx context.Context, params *protocol.InitializePara return nil, err } } + + var codeActionProvider interface{} + if len(params.Capabilities.TextDocument.CodeAction.CodeActionLiteralSupport.CodeActionKind.ValueSet) > 0 { + // If the client has specified CodeActionLiteralSupport, + // send the code actions we support. + // + // Using CodeActionOptions is only valid if codeActionLiteralSupport is set. + codeActionProvider = &protocol.CodeActionOptions{ + CodeActionKinds: s.getSupportedCodeActions(), + } + } else { + codeActionProvider = true + } return &protocol.InitializeResult{ Capabilities: protocol.ServerCapabilities{ - CodeActionProvider: true, + CodeActionProvider: codeActionProvider, CompletionProvider: &protocol.CompletionOptions{ TriggerCharacters: []string{"."}, }, diff --git a/internal/lsp/protocol/tsprotocol.go b/internal/lsp/protocol/tsprotocol.go index b9e81ebe20..b7a627e35b 100644 --- a/internal/lsp/protocol/tsprotocol.go +++ b/internal/lsp/protocol/tsprotocol.go @@ -1528,7 +1528,7 @@ type ServerCapabilities struct { * specified if the client states that it supports * `codeActionLiteralSupport` in its initial `initialize` request. */ - CodeActionProvider bool `json:"codeActionProvider,omitempty"` // boolean | CodeActionOptions + CodeActionProvider interface{} `json:"codeActionProvider,omitempty"` // boolean | CodeActionOptions /*CodeLensProvider defined: * The server provides code lens.