diff --git a/.gitignore b/.gitignore index edd1409a..93af3462 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,4 @@ __pycache__ .vscode/tasks.json .databricks +__debug_bin* diff --git a/cmd/lsp/lsp.go b/cmd/lsp/lsp.go index b5e1b322..701bec52 100644 --- a/cmd/lsp/lsp.go +++ b/cmd/lsp/lsp.go @@ -4,6 +4,7 @@ import ( "context" "github.com/databricks/cli/cmd/root" + "github.com/databricks/databricks-sdk-go/httpclient" "github.com/spf13/cobra" "github.com/tliron/commonlog" "github.com/tliron/glsp" @@ -16,8 +17,29 @@ const lsName = "databricks-lsp" var version string = "0.0.1" var handler protocol.Handler -func startServer(ctx context.Context) error { +var localClient = httpclient.NewApiClient(httpclient.ClientConfig{}) +type AnalyseResponse struct { + Diagnostics []protocol.Diagnostic `json:"diagnostics"` +} + +func callUcx(lspctx *glsp.Context, uri protocol.DocumentUri) error { + var res AnalyseResponse + err := localClient.Do(context.Background(), "GET", "http://localhost:8000/analyse", + httpclient.WithRequestData(map[string]any{ + "file_uri": uri, + }), httpclient.WithResponseUnmarshal(&res)) + if err != nil { + return err + } + lspctx.Notify(protocol.ServerTextDocumentPublishDiagnostics, &protocol.PublishDiagnosticsParams{ + URI: uri, + Diagnostics: res.Diagnostics, + }) + return nil +} + +func startServer(ctx context.Context) error { commonlog.Configure(1, nil) handler = protocol.Handler{ @@ -25,6 +47,54 @@ func startServer(ctx context.Context) error { Initialized: initialized, Shutdown: shutdown, SetTrace: setTrace, + TextDocumentCodeAction: func(context *glsp.Context, params *protocol.CodeActionParams) (any, error) { + foundUcx := false + var codeRange protocol.Range + for _, v := range params.Context.Diagnostics { + if v.Source == nil { + continue + } + if *v.Source == "databricks.labs.ucx" { + codeRange = v.Range + foundUcx = true + } + } + if !foundUcx { + return nil, nil + } + quickFix := protocol.CodeActionKindQuickFix + codeActions := []protocol.CodeAction{ + { + Title: "Replace table with migrated table", + Kind: &quickFix, + Edit: &protocol.WorkspaceEdit{ + DocumentChanges: []any{ + protocol.TextDocumentEdit{ + TextDocument: protocol.OptionalVersionedTextDocumentIdentifier{ + TextDocumentIdentifier: params.TextDocument, + }, + Edits: []any{ + protocol.TextEdit{ + Range: codeRange, + NewText: "[beep-v3]", + }, + }, + }, + }, + }, + }, + } + return codeActions, nil + }, + CodeActionResolve: func(context *glsp.Context, params *protocol.CodeAction) (*protocol.CodeAction, error) { + return params, nil + }, + TextDocumentDidOpen: func(context *glsp.Context, params *protocol.DidOpenTextDocumentParams) error { + return callUcx(context, params.TextDocument.URI) + }, + TextDocumentDidChange: func(context *glsp.Context, params *protocol.DidChangeTextDocumentParams) error { + return callUcx(context, params.TextDocument.URI) + }, } server := server.NewServer(&handler, lsName, false)