github.com/getgauge/gauge@v1.6.9/api/lang/capabilities.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package lang 8 9 import ( 10 "context" 11 "fmt" 12 "os" 13 "strconv" 14 "strings" 15 16 "github.com/getgauge/gauge/config" 17 "github.com/getgauge/gauge/util" 18 "github.com/sourcegraph/go-langserver/pkg/lsp" 19 "github.com/sourcegraph/jsonrpc2" 20 ) 21 22 type registrationParams struct { 23 Registrations []registration `json:"registrations"` 24 } 25 26 type registration struct { 27 Id string `json:"id"` 28 Method string `json:"method"` 29 RegisterOptions interface{} `json:"registerOptions"` 30 } 31 32 type codeLensRegistrationOptions struct { 33 textDocumentRegistrationOptions 34 ResolveProvider bool `json:"resolveProvider,omitempty"` 35 } 36 37 type didChangeWatchedFilesRegistrationOptions struct { 38 Watchers []fileSystemWatcher `json:"watchers"` 39 } 40 41 type fileSystemWatcher struct { 42 GlobPattern string `json:"globPattern"` 43 Kind int `json:"kind"` 44 } 45 46 type watchKind int 47 48 const ( 49 created watchKind = 1 50 deleted watchKind = 4 51 ) 52 53 type textDocumentRegistrationOptions struct { 54 DocumentSelector []documentSelector `json:"documentSelector"` 55 } 56 57 type textDocumentChangeRegistrationOptions struct { 58 textDocumentRegistrationOptions 59 SyncKind lsp.TextDocumentSyncKind `json:"syncKind,omitempty"` 60 } 61 62 type documentSelector struct { 63 Scheme string `json:"scheme"` 64 Language string `json:"language"` 65 Pattern string `json:"pattern"` 66 } 67 68 var clientCapabilities ClientCapabilities 69 70 type ClientCapabilities struct { 71 SaveFiles bool `json:"saveFiles,omitempty"` 72 } 73 74 func gaugeLSPCapabilities() lsp.InitializeResult { 75 kind := lsp.TDSKFull 76 return lsp.InitializeResult{ 77 Capabilities: lsp.ServerCapabilities{ 78 TextDocumentSync: &lsp.TextDocumentSyncOptionsOrKind{Kind: &kind, Options: &lsp.TextDocumentSyncOptions{Save: &lsp.SaveOptions{IncludeText: true}}}, 79 CompletionProvider: &lsp.CompletionOptions{ResolveProvider: true, TriggerCharacters: []string{"*", "* ", "\"", "<", ":", ","}}, 80 DocumentFormattingProvider: true, 81 CodeLensProvider: &lsp.CodeLensOptions{ResolveProvider: false}, 82 DefinitionProvider: true, 83 CodeActionProvider: true, 84 DocumentSymbolProvider: true, 85 WorkspaceSymbolProvider: true, 86 RenameProvider: true, 87 }, 88 } 89 } 90 91 func registerFileWatcher(conn jsonrpc2.JSONRPC2, ctx context.Context) error { 92 fileExtensions := strings.Join(util.GaugeFileExtensions(), ",") 93 regParams := didChangeWatchedFilesRegistrationOptions{ 94 Watchers: []fileSystemWatcher{{ 95 GlobPattern: strings.Replace(config.ProjectRoot, util.WindowsSep, util.UnixSep, -1) + "/**/*{" + fileExtensions + "}", 96 Kind: int(created) + int(deleted), 97 }}, 98 } 99 var result interface{} 100 return conn.Call(ctx, "client/registerCapability", registrationParams{[]registration{ 101 {Id: "gauge-fileWatcher", Method: "workspace/didChangeWatchedFiles", RegisterOptions: regParams}, 102 }}, &result) 103 } 104 105 func registerRunnerCapabilities(conn jsonrpc2.JSONRPC2, ctx context.Context) error { 106 if lRunner.lspID == "" { 107 return fmt.Errorf("current runner is not compatible with gauge LSP") 108 } 109 110 implFileGlobPatternResponse, err := globPatternRequest() 111 if err != nil { 112 return err 113 } 114 filePatterns := make([]fileSystemWatcher, 0) 115 documentSelectors := make([]documentSelector, 0) 116 for _, globPattern := range implFileGlobPatternResponse.GlobPatterns { 117 filePatterns = append(filePatterns, fileSystemWatcher{ 118 GlobPattern: globPattern, 119 Kind: int(created) + int(deleted), 120 }) 121 documentSelectors = append(documentSelectors, documentSelector{ 122 Scheme: "file", 123 Language: lRunner.lspID, 124 Pattern: globPattern, 125 }) 126 } 127 var result interface{} 128 var registrations = []registration{ 129 {Id: "gauge-runner-didOpen", Method: "textDocument/didOpen", RegisterOptions: textDocumentRegistrationOptions{DocumentSelector: documentSelectors}}, 130 {Id: "gauge-runner-didClose", Method: "textDocument/didClose", RegisterOptions: textDocumentRegistrationOptions{DocumentSelector: documentSelectors}}, 131 {Id: "gauge-runner-didChange", Method: "textDocument/didChange", RegisterOptions: textDocumentChangeRegistrationOptions{textDocumentRegistrationOptions: textDocumentRegistrationOptions{DocumentSelector: documentSelectors}, SyncKind: lsp.TDSKFull}}, 132 {Id: "gauge-runner-fileWatcher", Method: "workspace/didChangeWatchedFiles", RegisterOptions: didChangeWatchedFilesRegistrationOptions{Watchers: filePatterns}}, 133 } 134 registrations = addReferenceCodeLensRegistration(registrations, documentSelectors) 135 return conn.Call(ctx, "client/registerCapability", registrationParams{registrations}, &result) 136 } 137 138 func addReferenceCodeLensRegistration(registrations []registration, selectors []documentSelector) []registration { 139 if enabled, err := strconv.ParseBool(os.Getenv("gauge_lsp_reference_codelens")); err == nil && !enabled { 140 return registrations 141 } 142 codeLensRegistration := registration{Id: "gauge-runner-codelens", 143 Method: "textDocument/codeLens", 144 RegisterOptions: codeLensRegistrationOptions{ 145 textDocumentRegistrationOptions: textDocumentRegistrationOptions{ 146 DocumentSelector: selectors, 147 }, 148 ResolveProvider: false}, 149 } 150 return append(registrations, codeLensRegistration) 151 }