Skip to content

Commit 918e921

Browse files
committed
Update ServerCapabilities to match version 3.14 of the LSP spec
1 parent c52b337 commit 918e921

File tree

7 files changed

+259
-72
lines changed

7 files changed

+259
-72
lines changed

Sources/LanguageServerProtocol/ServerCapabilities.swift

Lines changed: 217 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -13,26 +13,46 @@
1313
/// Capabilities provided by the language server.
1414
public struct ServerCapabilities: Codable, Hashable {
1515

16+
/// Defines how text documents are synced. Is either a detailed structure defining each notification or
17+
/// for backwards compatibility the TextDocumentSyncKind number. If omitted it defaults to `TextDocumentSyncKind.None`.
1618
public var textDocumentSync: TextDocumentSyncOptions?
1719

20+
/// Whether the server provides "textDocument/hover".
21+
public var hoverProvider: Bool?
22+
1823
/// Whether the server provides code-completion.
1924
public var completionProvider: CompletionOptions?
2025

21-
/// Whether the server provides "textDocument/hover".
22-
public var hoverProvider: Bool?
26+
/// The server provides signature help support.
27+
public var signatureHelpProvider: SignatureHelpOptions?
2328

2429
/// Whether the server provides "textDocument/definition".
2530
public var definitionProvider: Bool?
2631

32+
/// The server provides Goto Type Definition support.
33+
public var typeDefinitionProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>?
34+
2735
/// Whether the server provides "textDocument/implementation".
28-
public var implementationProvider: Bool?
36+
public var implementationProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>?
2937

3038
/// Whether the server provides "textDocument/references".
3139
public var referencesProvider: Bool?
3240

3341
/// Whether the server provides "textDocument/documentHighlight".
3442
public var documentHighlightProvider: Bool?
3543

44+
/// Whether the server provides "textDocument/documentSymbol"
45+
public var documentSymbolProvider: Bool?
46+
47+
/// The server provides workspace symbol support.
48+
public var workspaceSymbolProvider: Bool?
49+
50+
/// Whether the server provides "textDocument/codeAction".
51+
public var codeActionProvider: ValueOrBool<CodeActionServerCapabilities>?
52+
53+
/// The server provides code lens.
54+
public var codeLensProvider: CodeLensOptions?
55+
3656
/// Whether the server provides "textDocument/formatting".
3757
public var documentFormattingProvider: Bool?
3858

@@ -42,85 +62,112 @@ public struct ServerCapabilities: Codable, Hashable {
4262
/// Whether the server provides "textDocument/onTypeFormatting".
4363
public var documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions?
4464

45-
/// Whether the server provides "textDocument/foldingRange".
46-
public var foldingRangeProvider: Bool?
65+
/// The server provides rename support. RenameOptions may only be specified if the client states that it supports `prepareSupport` in its initial `initialize` request.
66+
public var renameProvider: ValueOrBool<RenameOptions>?
4767

48-
/// Whether the server provides "textDocument/documentSymbol"
49-
public var documentSymbolProvider: Bool?
68+
/// The server provides document link support.
69+
public var documentLinkProvider: DocumentLinkOptions?
5070

5171
/// Whether the server provides "textDocument/documentColor" and "textDocument/colorPresentation".
52-
public var colorProvider: Bool?
72+
public var colorProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>?
5373

54-
/// Whether the server provides "textDocument/codeAction".
55-
public var codeActionProvider: CodeActionServerCapabilities?
74+
/// Whether the server provides "textDocument/foldingRange".
75+
public var foldingRangeProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>?
5676

57-
/// The server provides workspace symbol support.
58-
public var workspaceSymbolProvider: Bool?
77+
public var declarationProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>?
5978

6079
/// Whether the server provides "workspace/executeCommand".
6180
public var executeCommandProvider: ExecuteCommandOptions?
6281

63-
// TODO: fill-in the rest.
82+
public var workspace: WorkspaceServerCapabilities?
83+
84+
public var experimental: LSPAny?
6485

6586
public init(
6687
textDocumentSync: TextDocumentSyncOptions? = nil,
67-
completionProvider: CompletionOptions? = nil,
6888
hoverProvider: Bool? = nil,
89+
completionProvider: CompletionOptions? = nil,
90+
signatureHelpProvider: SignatureHelpOptions? = nil,
6991
definitionProvider: Bool? = nil,
70-
implementationProvider: Bool? = nil,
92+
typeDefinitionProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>? = nil,
93+
implementationProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>? = nil,
7194
referencesProvider: Bool? = nil,
7295
documentHighlightProvider: Bool? = nil,
96+
documentSymbolProvider: Bool? = nil,
97+
workspaceSymbolProvider: Bool? = nil,
98+
codeActionProvider: ValueOrBool<CodeActionServerCapabilities>? = nil,
99+
codeLensProvider: CodeLensOptions? = nil,
73100
documentFormattingProvider: Bool? = nil,
74101
documentRangeFormattingProvider: Bool? = nil,
75102
documentOnTypeFormattingProvider: DocumentOnTypeFormattingOptions? = nil,
76-
foldingRangeProvider: Bool? = nil,
77-
documentSymbolProvider: Bool? = nil,
78-
colorProvider: Bool? = nil,
79-
codeActionProvider: CodeActionServerCapabilities? = nil,
80-
workspaceSymbolProvider: Bool? = nil,
81-
executeCommandProvider: ExecuteCommandOptions? = nil
82-
)
103+
renameProvider: ValueOrBool<RenameOptions>? = nil,
104+
documentLinkProvider: DocumentLinkOptions? = nil,
105+
colorProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>? = nil,
106+
foldingRangeProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>? = nil,
107+
declarationProvider: ValueOrBool<TextDocumentAndStaticRegistrationOptions>? = nil,
108+
executeCommandProvider: ExecuteCommandOptions? = nil,
109+
workspace: WorkspaceServerCapabilities? = nil,
110+
experimental: LSPAny? = nil
111+
)
83112
{
84113
self.textDocumentSync = textDocumentSync
85-
self.completionProvider = completionProvider
86114
self.hoverProvider = hoverProvider
115+
self.completionProvider = completionProvider
116+
self.signatureHelpProvider = signatureHelpProvider
87117
self.definitionProvider = definitionProvider
118+
self.typeDefinitionProvider = typeDefinitionProvider
88119
self.implementationProvider = implementationProvider
89120
self.referencesProvider = referencesProvider
90121
self.documentHighlightProvider = documentHighlightProvider
122+
self.documentSymbolProvider = documentSymbolProvider
123+
self.workspaceSymbolProvider = workspaceSymbolProvider
124+
self.codeActionProvider = codeActionProvider
125+
self.codeLensProvider = codeLensProvider
91126
self.documentFormattingProvider = documentFormattingProvider
92127
self.documentRangeFormattingProvider = documentRangeFormattingProvider
93128
self.documentOnTypeFormattingProvider = documentOnTypeFormattingProvider
94-
self.foldingRangeProvider = foldingRangeProvider
95-
self.documentSymbolProvider = documentSymbolProvider
129+
self.renameProvider = renameProvider
130+
self.documentLinkProvider = documentLinkProvider
96131
self.colorProvider = colorProvider
97-
self.codeActionProvider = codeActionProvider
98-
self.workspaceSymbolProvider = workspaceSymbolProvider
132+
self.foldingRangeProvider = foldingRangeProvider
133+
self.declarationProvider = declarationProvider
99134
self.executeCommandProvider = executeCommandProvider
135+
self.workspace = workspace
136+
self.experimental = experimental
100137
}
138+
}
101139

102-
public init(from decoder: Decoder) throws {
103-
let container = try decoder.container(keyedBy: CodingKeys.self)
104-
self.completionProvider = try container.decodeIfPresent(CompletionOptions.self, forKey: .completionProvider)
105-
self.hoverProvider = try container.decodeIfPresent(Bool.self, forKey: .hoverProvider)
106-
self.definitionProvider = try container.decodeIfPresent(Bool.self, forKey: .definitionProvider)
107-
self.implementationProvider = try container.decodeIfPresent(Bool.self, forKey: .implementationProvider)
108-
self.foldingRangeProvider = try container.decodeIfPresent(Bool.self, forKey: .foldingRangeProvider)
109-
self.documentSymbolProvider = try container.decodeIfPresent(Bool.self, forKey: .documentSymbolProvider)
110-
self.colorProvider = try container.decodeIfPresent(Bool.self, forKey: .colorProvider)
111-
self.codeActionProvider = try container.decodeIfPresent(CodeActionServerCapabilities.self, forKey: .codeActionProvider)
112-
self.workspaceSymbolProvider = try container.decodeIfPresent(Bool.self, forKey: .workspaceSymbolProvider)
113-
self.executeCommandProvider = try container.decodeIfPresent(ExecuteCommandOptions.self, forKey: .executeCommandProvider)
114-
115-
if let textDocumentSync = try? container.decode(TextDocumentSyncOptions.self, forKey: .textDocumentSync) {
116-
self.textDocumentSync = textDocumentSync
117-
118-
} else if let kind = try? container.decode(TextDocumentSyncKind.self, forKey: .textDocumentSync) {
119-
// Legacy response
120-
self.textDocumentSync = TextDocumentSyncOptions(openClose: nil, change: kind, willSave: nil, willSaveWaitUntil: nil, save: nil)
140+
public enum ValueOrBool<ValueType: Codable>: Codable, Hashable where ValueType: Hashable {
141+
case bool(Bool)
142+
case value(ValueType)
143+
144+
/// A option is supported if either its bool value is `true` or the value is specified
145+
public var isSupported: Bool {
146+
switch self {
147+
case .bool(let value):
148+
return value
149+
case .value(_):
150+
return true
151+
}
152+
}
121153

154+
public init(from decoder: Decoder) throws {
155+
if let bool = try? Bool(from: decoder) {
156+
self = .bool(bool)
157+
} else if let value = try? ValueType(from: decoder) {
158+
self = .value(value)
122159
} else {
123-
self.textDocumentSync = nil
160+
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected Bool or \(ValueType.self)")
161+
throw DecodingError.dataCorrupted(context)
162+
}
163+
}
164+
165+
public func encode(to encoder: Encoder) throws {
166+
switch self {
167+
case .bool(let bool):
168+
try bool.encode(to: encoder)
169+
case .value(let value):
170+
try value.encode(to: encoder)
124171
}
125172
}
126173
}
@@ -152,13 +199,36 @@ public struct TextDocumentSyncOptions: Codable, Hashable {
152199
/// Whether save notifications should be sent to the server.
153200
public var save: SaveOptions?
154201

155-
public init(openClose: Bool? = true, change: TextDocumentSyncKind? = .incremental, willSave: Bool? = true, willSaveWaitUntil: Bool? = false, save: SaveOptions? = SaveOptions()) {
202+
public init(openClose: Bool? = true,
203+
change: TextDocumentSyncKind? = .incremental,
204+
willSave: Bool? = true,
205+
willSaveWaitUntil: Bool? = false,
206+
save: SaveOptions? = SaveOptions()) {
156207
self.openClose = openClose
157208
self.change = change
158209
self.willSave = willSave
159210
self.willSaveWaitUntil = willSaveWaitUntil
160211
self.save = save
161212
}
213+
214+
public init(from decoder: Decoder) throws {
215+
do {
216+
let container = try decoder.container(keyedBy: Self.CodingKeys)
217+
self.openClose = try container.decodeIfPresent(Bool.self, forKey: .openClose)
218+
self.change = try container.decodeIfPresent(TextDocumentSyncKind.self, forKey: .change)
219+
self.willSave = try container.decodeIfPresent(Bool.self, forKey: .willSave)
220+
self.willSaveWaitUntil = try container.decodeIfPresent(Bool.self, forKey: .willSaveWaitUntil)
221+
self.save = try container.decodeIfPresent(SaveOptions.self, forKey: .save)
222+
return
223+
} catch {}
224+
do {
225+
// Try decoding self as standalone TextDocumentSyncKind
226+
self.change = try TextDocumentSyncKind(from: decoder)
227+
return
228+
} catch {}
229+
let context = DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Expected TextDocumentSyncOptions or TextDocumentSyncKind")
230+
throw DecodingError.dataCorrupted(context)
231+
}
162232
}
163233

164234
public enum TextDocumentSyncKind: Int, Codable, Hashable {
@@ -186,6 +256,55 @@ public struct CompletionOptions: Codable, Hashable {
186256
}
187257
}
188258

259+
public struct SignatureHelpOptions: Codable, Hashable {
260+
/// The characters that trigger signature help automatically.
261+
public var triggerCharacters: [String]?
262+
263+
public init(triggerCharacters: [String]? = nil) {
264+
self.triggerCharacters = triggerCharacters
265+
}
266+
}
267+
268+
public struct DocumentFilter: Codable, Hashable {
269+
/// A language id, like `typescript`.
270+
public var language: String?
271+
272+
/// A Uri scheme, like `file` or `untitled`.
273+
public var scheme: String?
274+
275+
/// A glob pattern, like `*.{ts,js}`.
276+
///
277+
/// Glob patterns can have the following syntax:
278+
/// - `*` to match one or more characters in a path segment
279+
/// - `?` to match on one character in a path segment
280+
/// - `**` to match any number of path segments, including none
281+
/// - `{}` to group conditions (e.g. `**​/*.{ts,js}` matches all TypeScript and JavaScript files)
282+
/// - `[]` to declare a range of characters to match in a path segment (e.g., `example.[0-9]` to match on `example.0`, `example.1`, …)
283+
/// - `[!...]` to negate a range of characters to match in a path segment (e.g., `example.[!0-9]` to match on `example.a`, `example.b`, but not `example.0`)
284+
public var pattern: String?
285+
286+
public init(language: String? = nil, scheme: String? = nil, pattern: String? = nil) {
287+
self.language = language
288+
self.scheme = scheme
289+
self.pattern = pattern
290+
}
291+
}
292+
293+
public typealias DocumentSelector = [DocumentFilter]
294+
295+
public struct TextDocumentAndStaticRegistrationOptions: Codable, Hashable {
296+
/// A document selector to identify the scope of the registration. If set to null the document selector provided on the client side will be used.
297+
public var documentSelector: DocumentSelector?
298+
299+
/// The id used to register the request. The id can be used to deregister the request again. See also Registration#id
300+
public var id: String?
301+
302+
public init(documentSelector: DocumentSelector? = nil, id: String? = nil) {
303+
self.documentSelector = documentSelector
304+
self.id = id
305+
}
306+
}
307+
189308
public struct DocumentOnTypeFormattingOptions: Codable, Hashable {
190309

191310
/// A character that sould trigger formatting (e.g. '}').
@@ -253,6 +372,15 @@ public struct CodeActionOptions: Codable, Hashable {
253372
}
254373
}
255374

375+
public struct CodeLensOptions: Codable, Hashable {
376+
/// Code lens has a resolve provider as well.
377+
public var resolveProvider: Bool?
378+
379+
public init(resolveProvider: Bool? = nil) {
380+
self.resolveProvider = resolveProvider
381+
}
382+
}
383+
256384
public struct ExecuteCommandOptions: Codable, Hashable {
257385

258386
/// The commands to be executed on this server.
@@ -262,3 +390,44 @@ public struct ExecuteCommandOptions: Codable, Hashable {
262390
self.commands = commands
263391
}
264392
}
393+
394+
public struct RenameOptions: Codable, Hashable {
395+
/// Renames should be checked and tested before being executed.
396+
public var prepareProvider: Bool?
397+
398+
public init(prepareProvider: Bool? = nil) {
399+
self.prepareProvider = prepareProvider
400+
}
401+
}
402+
403+
public struct DocumentLinkOptions: Codable, Hashable {
404+
/// Document links have a resolve provider as well.
405+
public var resolveProvider: Bool?
406+
407+
public init(resolveProvider: Bool? = nil) {
408+
self.resolveProvider = resolveProvider
409+
}
410+
}
411+
412+
public struct WorkspaceServerCapabilities: Codable, Hashable {
413+
public struct WorkspaceFolders: Codable, Hashable {
414+
/// The server has support for workspace folders
415+
public var supported: Bool?
416+
417+
/// Whether the server wants to receive workspace folder change notifications.
418+
///
419+
/// If a strings is provided the string is treated as a ID under which the notification is registered on the client side. The ID can be used to unregister for these events using the `client/unregisterCapability` request.
420+
public var changeNotifications: ValueOrBool<String>?
421+
422+
public init(supported: Bool? = nil, changeNotifications: ValueOrBool<String>? = nil) {
423+
self.supported = supported
424+
self.changeNotifications = changeNotifications
425+
}
426+
}
427+
428+
public var workspaceFolders: WorkspaceFolders?
429+
430+
public init(workspaceFolders: WorkspaceFolders? = nil) {
431+
self.workspaceFolders = workspaceFolders
432+
}
433+
}

0 commit comments

Comments
 (0)