Skip to content

Commit

Permalink
docs(lsp): more completions. fix bug with completions.
Browse files Browse the repository at this point in the history
Completions were sometimes not being triggering correctly.
  • Loading branch information
gak committed Jun 16, 2024
1 parent 2f92517 commit c36af12
Show file tree
Hide file tree
Showing 16 changed files with 226 additions and 13 deletions.
66 changes: 57 additions & 9 deletions lsp/completion.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lsp

import (
_ "embed"
"fmt"
"os"
"strings"

Expand All @@ -18,24 +19,76 @@ var enumTypeCompletionDocs string
//go:embed markdown/completion/enumValue.md
var enumValueCompletionDocs string

//go:embed markdown/completion/typeAlias.md
var typeAliasCompletionDocs string

//go:embed markdown/completion/ingress.md
var ingressCompletionDocs string

//go:embed markdown/completion/cron.md
var cronCompletionDocs string

//go:embed markdown/completion/retry.md
var retryCompletionDocs string

//go:embed markdown/completion/configDeclare.md
var declareConfigCompletionDocs string

//go:embed markdown/completion/configGet.md
var getConfigCompletionDocs string

//go:embed markdown/completion/secretDeclare.md
var declareSecretCompletionDocs string

//go:embed markdown/completion/secretGet.md
var getSecretCompletionDocs string

//go:embed markdown/completion/pubSubTopic.md
var declarePubSubTopicCompletionDocs string

//go:embed markdown/completion/pubSubSubscription.md
var declarePubSubSubscriptionCompletionDocs string

//go:embed markdown/completion/pubSubSink.md
var definePubSubSinkCompletionDocs string

//go:embed markdown/completion/pubSubPublish.md
var publishPubSubEventCompletionDocs string

// Markdown is split by "---". First half is completion docs, second half is insert text.
var completionItems = []protocol.CompletionItem{
completionItem("ftl:verb", "FTL Verb", verbCompletionDocs),
completionItem("ftl:enum (sum type)", "FTL Enum (sum type)", enumTypeCompletionDocs),
completionItem("ftl:enum (value)", "FTL Enum (value type)", enumValueCompletionDocs),
completionItem("ftl:typealias", "FTL Type Alias", typeAliasCompletionDocs),
completionItem("ftl:ingress", "FTL Ingress", ingressCompletionDocs),
completionItem("ftl:cron", "FTL Cron", cronCompletionDocs),
completionItem("ftl:retry", "FTL Retry", retryCompletionDocs),
completionItem("config:declare", "Declare config", declareConfigCompletionDocs),
completionItem("config:get", "Get config", getConfigCompletionDocs),
completionItem("secret:declare", "Declare secret", declareSecretCompletionDocs),
completionItem("secret:get", "Get secret", getSecretCompletionDocs),
completionItem("pubsub:topic", "Declare PubSub topic", declarePubSubTopicCompletionDocs),
completionItem("pubsub:subscription", "Declare a PubSub subscription", declarePubSubSubscriptionCompletionDocs),
completionItem("pubsub:sink", "Define a PubSub sink", definePubSubSinkCompletionDocs),
completionItem("pubsub:publish", "Publish a PubSub event", publishPubSubEventCompletionDocs),
}

func completionItem(label, detail, markdown string) protocol.CompletionItem {
snippetKind := protocol.CompletionItemKindSnippet
insertTextFormat := protocol.InsertTextFormatSnippet

// Split markdown by "---"
// First half is completion docs, second half is insert text
parts := strings.Split(markdown, "---")
if len(parts) != 2 {
panic("invalid markdown. must contain exactly one '---' to separate completion docs from insert text")
}

insertText := strings.TrimSpace(parts[1])
// Warn if we see two spaces in the insert text.
if strings.Contains(insertText, " ") {
fmt.Fprintf(os.Stderr, "warning: completion item %q contains two spaces in the insert text. Use tabs instead!\n", label)
}

return protocol.CompletionItem{
Label: label,
Kind: &snippetKind,
Expand All @@ -59,7 +112,7 @@ func (s *Server) textDocumentCompletion() protocol.TextDocumentCompletionFunc {
return nil, nil
}

line := int(position.Line - 1)
line := int(position.Line)
if line >= len(doc.lines) {
return nil, nil
}
Expand All @@ -70,7 +123,7 @@ func (s *Server) textDocumentCompletion() protocol.TextDocumentCompletionFunc {
character = len(lineContent)
}

prefix := lineContent[:character]
prefix := lineContent[character:]

// Filter completion items based on the prefix
var filteredItems []protocol.CompletionItem
Expand Down Expand Up @@ -104,8 +157,3 @@ func (s *Server) completionItemResolve() protocol.CompletionItemResolveFunc {
return params, nil
}
}

func stringPtr(v string) *string {
s := v
return &s
}
9 changes: 9 additions & 0 deletions lsp/markdown/completion/configDeclare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for declaring a config variable.

```go
var defaultUser = ftl.Config[string]("default")
```

See https://tbd54566975.github.io/ftl/docs/reference/secretsconfig/
---
var ${1:configVar} = ftl.Config[${2:Type}](${3:default})
9 changes: 9 additions & 0 deletions lsp/markdown/completion/configGet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for getting a config variable.

```go
username = defaultUser.Get(ctx)
```

See https://tbd54566975.github.io/ftl/docs/reference/secretsconfig/
---
${1:value} := ${2:configVar}.Get(ctx)
18 changes: 18 additions & 0 deletions lsp/markdown/completion/cron.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Snippet for declaring a cron job.

```go
//ftl:cron 0 * * * *
func Hourly(ctx context.Context) {}

//ftl:cron 6h
func EverySixHours(ctx context.Context) {}
```

See https://tbd54566975.github.io/ftl/docs/reference/cron/
---

//ftl:cron ${1:Schedule}
func ${2:Name}(ctx context.Context) {
${3:// TODO: Implement}
}
```
4 changes: 3 additions & 1 deletion lsp/markdown/completion/enumType.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Snippet for defining a type enum (sum types).
Snippet for declare a type enum (sum types).

```go
//ftl:enum
Expand All @@ -9,6 +9,8 @@ const (
Value2 MyEnum = "Value2"
)
```

See https://tbd54566975.github.io/ftl/docs/reference/types/
---
//ftl:enum
type ${1:Enum} string
Expand Down
4 changes: 3 additions & 1 deletion lsp/markdown/completion/enumValue.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Snippet for defining a value enum.
Snippet for declaring a value enum.

```go
//ftl:enum
Expand All @@ -7,6 +7,8 @@ type Animal interface { animal() }
type Cat struct {}
func (Cat) animal() {}
```

See https://tbd54566975.github.io/ftl/docs/reference/types/
---
//ftl:enum
type ${1:Type} interface { ${2:interface}() }
Expand Down
39 changes: 39 additions & 0 deletions lsp/markdown/completion/ingress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Snippet for declaring an ingress function.

```go
type GetRequest struct {
UserID string `json:"userId"`
PostID string `json:"postId"`
}

type GetResponse struct {
Message string `json:"msg"`
}

//ftl:ingress GET /http/users/{userId}/posts
func Get(ctx context.Context, req builtin.HttpRequest[GetRequest]) (builtin.HttpResponse[GetResponse, string], error) {
return builtin.HttpResponse[GetResponse, string]{
Status: 200,
Body: ftl.Some(GetResponse{}),
}, nil
}
```

See https://tbd54566975.github.io/ftl/docs/reference/ingress/
---
type ${1:Func}Request struct {
${2:Field} ${3:Type} `json:"${4:field}"`
}

type ${1:Func}Response struct {
${5:Field} ${6:Type} `json:"${7:field}"`
}

//ftl:ingress ${8:GET} ${9:/url/path}
func ${1:Func}(ctx context.Context, req builtin.HttpRequest[${1:Func}Request]) (builtin.HttpResponse[${1:Func}Response, string], error) {
${7:// TODO: Implement}
return builtin.HttpResponse[${1:Func}Response, string]{
Status: 200,
Body: ftl.Some(${1:Func}Response{}),
}, nil
}
10 changes: 10 additions & 0 deletions lsp/markdown/completion/pubSubPublish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Snippet for publishing an event to a topic.

```go
invoicesTopic.Publish(ctx, Invoice{...})
```

See https://tbd54566975.github.io/ftl/docs/reference/pubsub/
---
${1:topicVar}.Publish(ctx, ${2:Type}{${3:...}})
```
16 changes: 16 additions & 0 deletions lsp/markdown/completion/pubSubSink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Snippet for a sink function that consume events from a PubSub subscription.

```go
//ftl:subscribe emailInvoices
func SendInvoiceEmail(ctx context.Context, in Invoice) error {
// ...
}
```

See https://tbd54566975.github.io/ftl/docs/reference/pubsub/
---
//ftl:subscribe ${1:subscriptionName}
func ${2:FunctionName}(ctx context.Context, in ${3:Type}) error {
${4:// TODO: Implement}
return nil
}
9 changes: 9 additions & 0 deletions lsp/markdown/completion/pubSubSubscription.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for declaring a subscription to a topic.

```go
var _ = ftl.Subscription(invoicesTopic, "emailInvoices")
```

See https://tbd54566975.github.io/ftl/docs/reference/pubsub/
---
var _ = ftl.Subscription(${1:topicVar}, "${2:subscriptionName}")
9 changes: 9 additions & 0 deletions lsp/markdown/completion/pubSubTopic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for declaring a topic.

```go
var invoicesTopic = ftl.Topic[Invoice]("invoices")
```

See https://tbd54566975.github.io/ftl/docs/reference/pubsub/
---
var ${1:topicVar} = ftl.Topic[${2:Type}]("${1:topicName}")
9 changes: 9 additions & 0 deletions lsp/markdown/completion/retry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for retrying an async operation.

```go
//ftl:retry [<attempts>] <min-backoff> [<max-backoff>]
```

See https://tbd54566975.github.io/ftl/docs/reference/retries/
---
//ftl:retry ${1:attempts} ${2:minBackoff} ${3:maxBackoff}
9 changes: 9 additions & 0 deletions lsp/markdown/completion/secretDeclare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for declaring a secret.

```go
var apiKey = ftl.Secret[string]("apiKey")
```

See https://tbd54566975.github.io/ftl/docs/reference/secretsconfig/
---
var ${1:secretVar} = ftl.Secret[${2:Type}](${3:default})
9 changes: 9 additions & 0 deletions lsp/markdown/completion/secretGet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Snippet for getting a secret.

```go
apiValue := apiKey.Get(ctx)
```

See https://tbd54566975.github.io/ftl/docs/reference/secretsconfig/
---
${1:value} := ${2:secretVar}.Get(ctx)
12 changes: 12 additions & 0 deletions lsp/markdown/completion/typeAlias.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Snippet for declaring a type alias.

```go
//ftl:typealias
type UserID string
```

See https://tbd54566975.github.io/ftl/docs/reference/types/
---
//ftl:typealias
type ${1:Alias} ${2:Type}
```
7 changes: 5 additions & 2 deletions lsp/markdown/completion/verb.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
Snippet for defining a verb function.
Snippet for declaring a verb function.

```go
//ftl:verb
func Name(ctx context.Context, req Request) (Response, error) {}
```

See https://tbd54566975.github.io/ftl/docs/reference/verbs/
---
type ${1:Request} struct {}
type ${2:Response} struct {}

//ftl:verb
func ${3:Name}(ctx context.Context, req ${1:Request}) (${2:Response}, error) {
return ${2:Response}{}, nil
${4:// TODO: Implement}
return ${2:Response}{}, nil
}

0 comments on commit c36af12

Please sign in to comment.