3 # Functions for managing the LSP server and client capabilities
5 import './options.vim' as opt
7 # Process the server capabilities
8 # interface ServerCapabilities
9 export def ProcessServerCaps(lspserver: dict<any>, caps: dict<any>)
10 var serverEncoding = 'utf-16'
11 if lspserver.caps->has_key('positionEncoding')
12 serverEncoding = lspserver.caps.positionEncoding
13 elseif lspserver.caps->has_key('~additionalInitResult_offsetEncoding')
14 serverEncoding = lspserver.caps['~additionalInitResult_offsetEncoding']
17 # one of 'utf-8', 'utf-16' or 'utf-32'
18 if serverEncoding == 'utf-8'
19 lspserver.posEncoding = 8
20 elseif serverEncoding == 'utf-16'
21 lspserver.posEncoding = 16
23 lspserver.posEncoding = 32
26 if has('patch-9.0.1629') && lspserver.posEncoding != 32
27 lspserver.needOffsetEncoding = true
29 lspserver.needOffsetEncoding = false
33 if lspserver.caps->has_key('completionProvider')
34 lspserver.isCompletionProvider = true
35 if lspserver.caps.completionProvider->has_key('resolveProvider')
36 lspserver.isCompletionResolveProvider =
37 lspserver.caps.completionProvider.resolveProvider
39 lspserver.isCompletionResolveProvider = false
42 lspserver.isCompletionProvider = false
43 lspserver.isCompletionResolveProvider = false
47 if lspserver.caps->has_key('definitionProvider')
48 if lspserver.caps.definitionProvider->type() == v:t_bool
49 lspserver.isDefinitionProvider = lspserver.caps.definitionProvider
51 lspserver.isDefinitionProvider = true
54 lspserver.isDefinitionProvider = false
58 if lspserver.caps->has_key('declarationProvider')
59 if lspserver.caps.declarationProvider->type() == v:t_bool
60 lspserver.isDeclarationProvider = lspserver.caps.declarationProvider
62 lspserver.isDeclarationProvider = true
65 lspserver.isDeclarationProvider = false
68 # typeDefinitionProvider
69 if lspserver.caps->has_key('typeDefinitionProvider')
70 if lspserver.caps.typeDefinitionProvider->type() == v:t_bool
71 lspserver.isTypeDefinitionProvider = lspserver.caps.typeDefinitionProvider
73 lspserver.isTypeDefinitionProvider = true
76 lspserver.isTypeDefinitionProvider = false
79 # implementationProvider
80 if lspserver.caps->has_key('implementationProvider')
81 if lspserver.caps.implementationProvider->type() == v:t_bool
82 lspserver.isImplementationProvider = lspserver.caps.implementationProvider
84 lspserver.isImplementationProvider = true
87 lspserver.isImplementationProvider = false
90 # signatureHelpProvider
91 if lspserver.caps->has_key('signatureHelpProvider')
92 lspserver.isSignatureHelpProvider = true
94 lspserver.isSignatureHelpProvider = false
98 if lspserver.caps->has_key('hoverProvider')
99 if lspserver.caps.hoverProvider->type() == v:t_bool
100 lspserver.isHoverProvider = lspserver.caps.hoverProvider
102 lspserver.isHoverProvider = true
105 lspserver.isHoverProvider = false
109 if lspserver.caps->has_key('referencesProvider')
110 if lspserver.caps.referencesProvider->type() == v:t_bool
111 lspserver.isReferencesProvider = lspserver.caps.referencesProvider
113 lspserver.isReferencesProvider = true
116 lspserver.isReferencesProvider = false
119 # documentHighlightProvider
120 if lspserver.caps->has_key('documentHighlightProvider')
121 if lspserver.caps.documentHighlightProvider->type() == v:t_bool
122 lspserver.isDocumentHighlightProvider =
123 lspserver.caps.documentHighlightProvider
125 lspserver.isDocumentHighlightProvider = true
128 lspserver.isDocumentHighlightProvider = false
131 # documentSymbolProvider
132 if lspserver.caps->has_key('documentSymbolProvider')
133 if lspserver.caps.documentSymbolProvider->type() == v:t_bool
134 lspserver.isDocumentSymbolProvider =
135 lspserver.caps.documentSymbolProvider
137 lspserver.isDocumentSymbolProvider = true
140 lspserver.isDocumentSymbolProvider = false
143 # documentFormattingProvider
144 if lspserver.caps->has_key('documentFormattingProvider')
145 if lspserver.caps.documentFormattingProvider->type() == v:t_bool
146 lspserver.isDocumentFormattingProvider =
147 lspserver.caps.documentFormattingProvider
149 lspserver.isDocumentFormattingProvider = true
152 lspserver.isDocumentFormattingProvider = false
155 # callHierarchyProvider
156 if lspserver.caps->has_key('callHierarchyProvider')
157 if lspserver.caps.callHierarchyProvider->type() == v:t_bool
158 lspserver.isCallHierarchyProvider =
159 lspserver.caps.callHierarchyProvider
161 lspserver.isCallHierarchyProvider = true
164 lspserver.isCallHierarchyProvider = false
167 # typeHierarchyProvider
168 if lspserver.caps->has_key('typeHierarchyProvider')
169 lspserver.isTypeHierarchyProvider = true
171 lspserver.isTypeHierarchyProvider = false
175 if lspserver.caps->has_key('renameProvider')
176 if lspserver.caps.renameProvider->type() == v:t_bool
177 lspserver.isRenameProvider = lspserver.caps.renameProvider
179 lspserver.isRenameProvider = true
182 lspserver.isRenameProvider = false
186 if lspserver.caps->has_key('codeActionProvider')
187 if lspserver.caps.codeActionProvider->type() == v:t_bool
188 lspserver.isCodeActionProvider = lspserver.caps.codeActionProvider
190 lspserver.isCodeActionProvider = true
193 lspserver.isCodeActionProvider = false
197 if lspserver.caps->has_key('codeLensProvider')
198 lspserver.isCodeLensProvider = true
199 if lspserver.caps.codeLensProvider->has_key('resolveProvider')
200 lspserver.isCodeLensResolveProvider = true
202 lspserver.isCodeLensResolveProvider = false
205 lspserver.isCodeLensProvider = false
208 # workspaceSymbolProvider
209 if lspserver.caps->has_key('workspaceSymbolProvider')
210 if lspserver.caps.workspaceSymbolProvider->type() == v:t_bool
211 lspserver.isWorkspaceSymbolProvider =
212 lspserver.caps.workspaceSymbolProvider
214 lspserver.isWorkspaceSymbolProvider = true
217 lspserver.isWorkspaceSymbolProvider = false
220 # selectionRangeProvider
221 if lspserver.caps->has_key('selectionRangeProvider')
222 if lspserver.caps.selectionRangeProvider->type() == v:t_bool
223 lspserver.isSelectionRangeProvider =
224 lspserver.caps.selectionRangeProvider
226 lspserver.isSelectionRangeProvider = true
229 lspserver.isSelectionRangeProvider = false
232 # foldingRangeProvider
233 if lspserver.caps->has_key('foldingRangeProvider')
234 if lspserver.caps.foldingRangeProvider->type() == v:t_bool
235 lspserver.isFoldingRangeProvider = lspserver.caps.foldingRangeProvider
237 lspserver.isFoldingRangeProvider = true
240 lspserver.isFoldingRangeProvider = false
244 if lspserver.caps->has_key('inlayHintProvider')
245 if lspserver.caps.inlayHintProvider->type() == v:t_bool
246 lspserver.isInlayHintProvider = lspserver.caps.inlayHintProvider
248 lspserver.isInlayHintProvider = true
251 lspserver.isInlayHintProvider = false
254 # clangdInlayHintsProvider
255 if lspserver.caps->has_key('clangdInlayHintsProvider')
256 lspserver.isClangdInlayHintsProvider =
257 lspserver.caps.clangdInlayHintsProvider
259 lspserver.isClangdInlayHintsProvider = false
262 # textDocumentSync capabilities
263 lspserver.supportsDidSave = false
264 # Default to TextDocumentSyncKind.None
265 lspserver.textDocumentSync = 0
266 if lspserver.caps->has_key('textDocumentSync')
267 if lspserver.caps.textDocumentSync->type() == v:t_bool
268 || lspserver.caps.textDocumentSync->type() == v:t_number
269 lspserver.supportsDidSave = lspserver.caps.textDocumentSync
270 lspserver.textDocumentSync = lspserver.caps.textDocumentSync
271 elseif lspserver.caps.textDocumentSync->type() == v:t_dict
273 if lspserver.caps.textDocumentSync->has_key('save')
274 if lspserver.caps.textDocumentSync.save->type() == v:t_bool
275 || lspserver.caps.textDocumentSync.save->type() == v:t_number
276 lspserver.supportsDidSave = lspserver.caps.textDocumentSync.save
277 elseif lspserver.caps.textDocumentSync.save->type() == v:t_dict
278 lspserver.supportsDidSave = true
282 if lspserver.caps.textDocumentSync->has_key('change')
283 lspserver.textDocumentSync = lspserver.caps.textDocumentSync.change
289 # Return all the LSP client capabilities
290 export def GetClientCaps(): dict<any>
291 # client capabilities (ClientCapabilities)
292 var clientCaps: dict<any> = {
294 workspaceFolders: true,
300 dynamicRegistration: false
303 dynamicRegistration: false,
304 codeActionLiteralSupport: {
306 valueSet: ['', 'quickfix', 'refactor', 'refactor.extract',
307 'refactor.inline', 'refactor.rewrite', 'source',
308 'source.organizeImports']
311 isPreferredSupport: true,
312 disabledSupport: true
315 dynamicRegistration: false
318 dynamicRegistration: false,
320 documentationFormat: ['markdown', 'plaintext'],
321 resolveSupport: {properties: ['detail', 'documentation']},
322 snippetSupport: opt.lspOptions.snippetSupport
324 completionItemKind: {valueSet: range(1, 25)}
327 dynamicRegistration: false,
328 hierarchicalDocumentSymbolSupport: true,
329 symbolKind: {valueSet: range(1, 25)}
332 contentFormat: ['markdown', 'plaintext']
334 foldingRange: {lineFoldingOnly: true},
335 inlayHint: {dynamicRegistration: false},
339 declaration: {linkSupport: true},
340 definition: {linkSupport: true},
341 typeDefinition: {linkSupport: true},
342 implementation: {linkSupport: true},
344 signatureInformation: {
345 documentationFormat: ['markdown', 'plaintext'],
346 activeParameterSupport: true
352 # Currently we always send character count as position offset,
353 # which meanas only utf-32 is supported.
354 # Adding utf-16 simply for good mesure, as I'm scared some servers will
355 # give up if they don't support utf-32 only.
356 positionEncodings: ['utf-32', 'utf-16']
358 # This is the way clangd expects to be informated about supported encodings:
359 # https://clangd.llvm.org/extensions#utf-8-offsets
360 offsetEncoding: ['utf-32', 'utf-16']
363 # Vim patch 1629 is needed to properly encode/decode UTF-16 offsets
364 if has('patch-9.0.1629')
365 clientCaps.general.positionEncodings = ['utf-32', 'utf-16', 'utf-8']
366 clientCaps.offsetEncoding = ['utf-32', 'utf-16', 'utf-8']
372 # vim: tabstop=8 shiftwidth=2 softtabstop=2