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 if lspserver.forceOffsetEncoding != ''
18 serverEncoding = lspserver.forceOffsetEncoding
21 # one of 'utf-8', 'utf-16' or 'utf-32'
22 if serverEncoding == 'utf-8'
23 lspserver.posEncoding = 8
24 elseif serverEncoding == 'utf-16'
25 lspserver.posEncoding = 16
27 lspserver.posEncoding = 32
30 if has('patch-9.0.1629') && lspserver.posEncoding != 32
31 lspserver.needOffsetEncoding = true
33 lspserver.needOffsetEncoding = false
37 if lspserver.caps->has_key('completionProvider')
38 lspserver.isCompletionProvider = true
39 if lspserver.caps.completionProvider->has_key('resolveProvider')
40 lspserver.isCompletionResolveProvider =
41 lspserver.caps.completionProvider.resolveProvider
43 lspserver.isCompletionResolveProvider = false
46 lspserver.isCompletionProvider = false
47 lspserver.isCompletionResolveProvider = false
51 if lspserver.caps->has_key('definitionProvider')
52 if lspserver.caps.definitionProvider->type() == v:t_bool
53 lspserver.isDefinitionProvider = lspserver.caps.definitionProvider
55 lspserver.isDefinitionProvider = true
58 lspserver.isDefinitionProvider = false
62 if lspserver.caps->has_key('declarationProvider')
63 if lspserver.caps.declarationProvider->type() == v:t_bool
64 lspserver.isDeclarationProvider = lspserver.caps.declarationProvider
66 lspserver.isDeclarationProvider = true
69 lspserver.isDeclarationProvider = false
72 # typeDefinitionProvider
73 if lspserver.caps->has_key('typeDefinitionProvider')
74 if lspserver.caps.typeDefinitionProvider->type() == v:t_bool
75 lspserver.isTypeDefinitionProvider = lspserver.caps.typeDefinitionProvider
77 lspserver.isTypeDefinitionProvider = true
80 lspserver.isTypeDefinitionProvider = false
83 # implementationProvider
84 if lspserver.caps->has_key('implementationProvider')
85 if lspserver.caps.implementationProvider->type() == v:t_bool
86 lspserver.isImplementationProvider = lspserver.caps.implementationProvider
88 lspserver.isImplementationProvider = true
91 lspserver.isImplementationProvider = false
94 # signatureHelpProvider
95 if lspserver.caps->has_key('signatureHelpProvider')
96 lspserver.isSignatureHelpProvider = true
98 lspserver.isSignatureHelpProvider = false
102 if lspserver.caps->has_key('hoverProvider')
103 if lspserver.caps.hoverProvider->type() == v:t_bool
104 lspserver.isHoverProvider = lspserver.caps.hoverProvider
106 lspserver.isHoverProvider = true
109 lspserver.isHoverProvider = false
113 if lspserver.caps->has_key('referencesProvider')
114 if lspserver.caps.referencesProvider->type() == v:t_bool
115 lspserver.isReferencesProvider = lspserver.caps.referencesProvider
117 lspserver.isReferencesProvider = true
120 lspserver.isReferencesProvider = false
123 # documentHighlightProvider
124 if lspserver.caps->has_key('documentHighlightProvider')
125 if lspserver.caps.documentHighlightProvider->type() == v:t_bool
126 lspserver.isDocumentHighlightProvider =
127 lspserver.caps.documentHighlightProvider
129 lspserver.isDocumentHighlightProvider = true
132 lspserver.isDocumentHighlightProvider = false
135 # documentSymbolProvider
136 if lspserver.caps->has_key('documentSymbolProvider')
137 if lspserver.caps.documentSymbolProvider->type() == v:t_bool
138 lspserver.isDocumentSymbolProvider =
139 lspserver.caps.documentSymbolProvider
141 lspserver.isDocumentSymbolProvider = true
144 lspserver.isDocumentSymbolProvider = false
147 # documentFormattingProvider
148 if lspserver.caps->has_key('documentFormattingProvider')
149 if lspserver.caps.documentFormattingProvider->type() == v:t_bool
150 lspserver.isDocumentFormattingProvider =
151 lspserver.caps.documentFormattingProvider
153 lspserver.isDocumentFormattingProvider = true
156 lspserver.isDocumentFormattingProvider = false
159 # callHierarchyProvider
160 if lspserver.caps->has_key('callHierarchyProvider')
161 if lspserver.caps.callHierarchyProvider->type() == v:t_bool
162 lspserver.isCallHierarchyProvider =
163 lspserver.caps.callHierarchyProvider
165 lspserver.isCallHierarchyProvider = true
168 lspserver.isCallHierarchyProvider = false
171 # typeHierarchyProvider
172 if lspserver.caps->has_key('typeHierarchyProvider')
173 lspserver.isTypeHierarchyProvider = true
175 lspserver.isTypeHierarchyProvider = false
179 if lspserver.caps->has_key('renameProvider')
180 if lspserver.caps.renameProvider->type() == v:t_bool
181 lspserver.isRenameProvider = lspserver.caps.renameProvider
183 lspserver.isRenameProvider = true
186 lspserver.isRenameProvider = false
190 if lspserver.caps->has_key('codeActionProvider')
191 if lspserver.caps.codeActionProvider->type() == v:t_bool
192 lspserver.isCodeActionProvider = lspserver.caps.codeActionProvider
194 lspserver.isCodeActionProvider = true
197 lspserver.isCodeActionProvider = false
201 if lspserver.caps->has_key('codeLensProvider')
202 lspserver.isCodeLensProvider = true
203 if lspserver.caps.codeLensProvider->has_key('resolveProvider')
204 lspserver.isCodeLensResolveProvider = true
206 lspserver.isCodeLensResolveProvider = false
209 lspserver.isCodeLensProvider = false
212 # workspaceSymbolProvider
213 if lspserver.caps->has_key('workspaceSymbolProvider')
214 if lspserver.caps.workspaceSymbolProvider->type() == v:t_bool
215 lspserver.isWorkspaceSymbolProvider =
216 lspserver.caps.workspaceSymbolProvider
218 lspserver.isWorkspaceSymbolProvider = true
221 lspserver.isWorkspaceSymbolProvider = false
224 # selectionRangeProvider
225 if lspserver.caps->has_key('selectionRangeProvider')
226 if lspserver.caps.selectionRangeProvider->type() == v:t_bool
227 lspserver.isSelectionRangeProvider =
228 lspserver.caps.selectionRangeProvider
230 lspserver.isSelectionRangeProvider = true
233 lspserver.isSelectionRangeProvider = false
236 # foldingRangeProvider
237 if lspserver.caps->has_key('foldingRangeProvider')
238 if lspserver.caps.foldingRangeProvider->type() == v:t_bool
239 lspserver.isFoldingRangeProvider = lspserver.caps.foldingRangeProvider
241 lspserver.isFoldingRangeProvider = true
244 lspserver.isFoldingRangeProvider = false
248 if lspserver.caps->has_key('inlayHintProvider')
249 if lspserver.caps.inlayHintProvider->type() == v:t_bool
250 lspserver.isInlayHintProvider = lspserver.caps.inlayHintProvider
252 lspserver.isInlayHintProvider = true
255 lspserver.isInlayHintProvider = false
258 # clangdInlayHintsProvider
259 if lspserver.caps->has_key('clangdInlayHintsProvider')
260 lspserver.isClangdInlayHintsProvider =
261 lspserver.caps.clangdInlayHintsProvider
263 lspserver.isClangdInlayHintsProvider = false
266 # textDocumentSync capabilities
267 lspserver.supportsDidSave = false
268 # Default to TextDocumentSyncKind.None
269 lspserver.textDocumentSync = 0
270 if lspserver.caps->has_key('textDocumentSync')
271 if lspserver.caps.textDocumentSync->type() == v:t_bool
272 || lspserver.caps.textDocumentSync->type() == v:t_number
273 lspserver.supportsDidSave = lspserver.caps.textDocumentSync
274 lspserver.textDocumentSync = lspserver.caps.textDocumentSync
275 elseif lspserver.caps.textDocumentSync->type() == v:t_dict
277 if lspserver.caps.textDocumentSync->has_key('save')
278 if lspserver.caps.textDocumentSync.save->type() == v:t_bool
279 || lspserver.caps.textDocumentSync.save->type() == v:t_number
280 lspserver.supportsDidSave = lspserver.caps.textDocumentSync.save
281 elseif lspserver.caps.textDocumentSync.save->type() == v:t_dict
282 lspserver.supportsDidSave = true
286 if lspserver.caps.textDocumentSync->has_key('change')
287 lspserver.textDocumentSync = lspserver.caps.textDocumentSync.change
293 # Return all the LSP client capabilities
294 export def GetClientCaps(): dict<any>
295 # client capabilities (ClientCapabilities)
296 var clientCaps: dict<any> = {
298 workspaceFolders: true,
304 dynamicRegistration: false
307 dynamicRegistration: false,
308 codeActionLiteralSupport: {
310 valueSet: ['', 'quickfix', 'refactor', 'refactor.extract',
311 'refactor.inline', 'refactor.rewrite', 'source',
312 'source.organizeImports']
315 isPreferredSupport: true,
316 disabledSupport: true
319 dynamicRegistration: false
322 dynamicRegistration: false,
324 documentationFormat: ['markdown', 'plaintext'],
325 resolveSupport: {properties: ['detail', 'documentation']},
326 snippetSupport: opt.lspOptions.snippetSupport,
327 insertReplaceSupport: false
329 completionItemKind: {valueSet: range(1, 25)}
332 dynamicRegistration: false,
333 hierarchicalDocumentSymbolSupport: true,
334 symbolKind: {valueSet: range(1, 25)}
337 contentFormat: ['markdown', 'plaintext']
339 foldingRange: {lineFoldingOnly: true},
340 inlayHint: {dynamicRegistration: false},
344 declaration: {linkSupport: true},
345 definition: {linkSupport: true},
346 typeDefinition: {linkSupport: true},
347 implementation: {linkSupport: true},
349 signatureInformation: {
350 documentationFormat: ['markdown', 'plaintext'],
351 activeParameterSupport: true
357 # Currently we always send character count as position offset,
358 # which meanas only utf-32 is supported.
359 # Adding utf-16 simply for good mesure, as I'm scared some servers will
360 # give up if they don't support utf-32 only.
361 positionEncodings: ['utf-32', 'utf-16']
363 # This is the way clangd expects to be informated about supported encodings:
364 # https://clangd.llvm.org/extensions#utf-8-offsets
365 offsetEncoding: ['utf-32', 'utf-16']
368 # Vim patch 1629 is needed to properly encode/decode UTF-16 offsets
369 if has('patch-9.0.1629')
370 clientCaps.general.positionEncodings = ['utf-32', 'utf-16', 'utf-8']
371 clientCaps.offsetEncoding = ['utf-32', 'utf-16', 'utf-8']
377 # vim: tabstop=8 shiftwidth=2 softtabstop=2