-
Notifications
You must be signed in to change notification settings - Fork 132
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add hooks for dynamic completion (#1017)
* Pass context to CandidatesAtPos * Add optional data to completion item response * Refactor `DecoderContext` creation Making `DecoderContext` public allows us to extend the context after creation. * Introduce hooks package and register first completion hook * Add `completionItem/resolve` handler * Update hcl-lang to 118ac45 * Avoid exposing CompletionItem data as null * Add completionItem/resolve test
- Loading branch information
Showing
16 changed files
with
218 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// Package hooks enables the implementation of hooks for dynamic | ||
// autocompletion. Hooks should be added to this package and | ||
// registered via AppendCompletionHooks in completion_hooks.go. | ||
package hooks | ||
|
||
import "github.com/hashicorp/terraform-ls/internal/state" | ||
|
||
type Hooks struct { | ||
ModStore *state.ModuleStore | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package hooks | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/hcl-lang/decoder" | ||
"github.com/zclconf/go-cty/cty" | ||
) | ||
|
||
func (h *Hooks) LocalModuleSources(ctx context.Context, value cty.Value) ([]decoder.Candidate, error) { | ||
candidates := make([]decoder.Candidate, 0) | ||
|
||
// Obtain indexed modules via h.modStore.List() | ||
// TODO filter modules inside .terraform | ||
// TODO build candidates | ||
|
||
return candidates, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package handlers | ||
|
||
import ( | ||
"github.com/hashicorp/hcl-lang/decoder" | ||
"github.com/hashicorp/terraform-ls/internal/hooks" | ||
) | ||
|
||
func (s *service) AppendCompletionHooks(ctx decoder.DecoderContext) { | ||
h := hooks.Hooks{ | ||
ModStore: s.modStore, | ||
} | ||
|
||
ctx.CompletionHooks["CompleteLocalModuleSources"] = h.LocalModuleSources | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package handlers | ||
|
||
import ( | ||
"context" | ||
|
||
"github.com/hashicorp/hcl-lang/decoder" | ||
ilsp "github.com/hashicorp/terraform-ls/internal/lsp" | ||
"github.com/hashicorp/terraform-ls/internal/mdplain" | ||
lsp "github.com/hashicorp/terraform-ls/internal/protocol" | ||
) | ||
|
||
func (svc *service) CompletionItemResolve(ctx context.Context, params lsp.CompletionItemWithResolveHook) (lsp.CompletionItemWithResolveHook, error) { | ||
cc, err := ilsp.ClientCapabilities(ctx) | ||
if err != nil { | ||
return params, err | ||
} | ||
|
||
if params.ResolveHook == nil { | ||
return params, nil | ||
} | ||
|
||
unresolvedCandidate := decoder.UnresolvedCandidate{ | ||
ResolveHook: params.ResolveHook, | ||
} | ||
|
||
resolvedCandidate, err := svc.decoder.ResolveCandidate(ctx, unresolvedCandidate) | ||
if err != nil || resolvedCandidate == nil { | ||
return params, err | ||
} | ||
|
||
if resolvedCandidate.Description.Value != "" { | ||
doc := resolvedCandidate.Description.Value | ||
|
||
// TODO: Revisit when MarkupContent is allowed as Documentation | ||
// https://github.com/golang/tools/blob/4783bc9b/internal/lsp/protocol/tsprotocol.go#L753 | ||
doc = mdplain.Clean(doc) | ||
params.Documentation = doc | ||
} | ||
if resolvedCandidate.Detail != "" { | ||
params.Detail = resolvedCandidate.Detail | ||
} | ||
if len(resolvedCandidate.AdditionalTextEdits) > 0 { | ||
snippetSupport := cc.TextDocument.Completion.CompletionItem.SnippetSupport | ||
params.AdditionalTextEdits = ilsp.TextEdits(resolvedCandidate.AdditionalTextEdits, snippetSupport) | ||
} | ||
|
||
return params, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
package handlers | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"testing" | ||
|
||
tfjson "github.com/hashicorp/terraform-json" | ||
"github.com/hashicorp/terraform-ls/internal/langserver" | ||
"github.com/hashicorp/terraform-ls/internal/langserver/session" | ||
) | ||
|
||
func TestCompletionResolve_withoutInitialization(t *testing.T) { | ||
ls := langserver.NewLangServerMock(t, NewMockSession(nil)) | ||
stop := ls.Start(t) | ||
defer stop() | ||
|
||
ls.CallAndExpectError(t, &langserver.CallRequest{ | ||
Method: "completionItem/resolve", | ||
ReqParams: "{}"}, session.SessionNotInitialized.Err()) | ||
} | ||
|
||
func TestCompletionResolve_withoutHook(t *testing.T) { | ||
tmpDir := TempDir(t) | ||
InitPluginCache(t, tmpDir.Path()) | ||
|
||
var testSchema tfjson.ProviderSchemas | ||
err := json.Unmarshal([]byte(testModuleSchemaOutput), &testSchema) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
ls := langserver.NewLangServerMock(t, NewMockSession(nil)) | ||
stop := ls.Start(t) | ||
defer stop() | ||
|
||
ls.Call(t, &langserver.CallRequest{ | ||
Method: "initialize", | ||
ReqParams: fmt.Sprintf(`{ | ||
"capabilities": {}, | ||
"rootUri": %q, | ||
"processId": 12345 | ||
}`, tmpDir.URI)}) | ||
ls.Notify(t, &langserver.CallRequest{ | ||
Method: "initialized", | ||
ReqParams: "{}", | ||
}) | ||
|
||
ls.CallAndExpectResponse(t, &langserver.CallRequest{ | ||
Method: "completionItem/resolve", | ||
ReqParams: fmt.Sprintf(`{ | ||
"label": "\"test\"", | ||
"kind": 1, | ||
"data": { | ||
"resolve_hook": "test", | ||
"path": "%s/main.tf" | ||
} | ||
}`, TempDir(t).URI), | ||
}, fmt.Sprintf(`{ | ||
"jsonrpc": "2.0", | ||
"id": 2, | ||
"result": { | ||
"label": "\"test\"", | ||
"labelDetails": {}, | ||
"kind": 1, | ||
"data": { | ||
"resolve_hook": "test", | ||
"path": "%s/main.tf" | ||
} | ||
} | ||
}`, TempDir(t).URI)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package protocol | ||
|
||
import "github.com/hashicorp/hcl-lang/lang" | ||
|
||
type CompletionItemWithResolveHook struct { | ||
CompletionItem | ||
|
||
ResolveHook *lang.ResolveHook `json:"data,omitempty"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters