]> Sergey Matveev's repositories - vim-lsp.git/blob - autoload/lsp/capabilities.vim
Update the client capabilities. Pass buffer number to autocmd handler functions...
[vim-lsp.git] / autoload / lsp / capabilities.vim
1 vim9script
2
3 # Functions for managing the LSP server and client capabilities
4
5 import './options.vim' as opt
6
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']
15   endif
16
17   if lspserver.forceOffsetEncoding != ''
18     serverEncoding = lspserver.forceOffsetEncoding
19   endif
20
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
26   else
27     lspserver.posEncoding = 32
28   endif
29
30   if has('patch-9.0.1629') && lspserver.posEncoding != 32
31     lspserver.needOffsetEncoding = true
32   else
33     lspserver.needOffsetEncoding = false
34   endif
35
36   # completionProvider
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
42     else
43       lspserver.isCompletionResolveProvider = false
44     endif
45   else
46     lspserver.isCompletionProvider = false
47     lspserver.isCompletionResolveProvider = false
48   endif
49
50   # definitionProvider
51   if lspserver.caps->has_key('definitionProvider')
52     if lspserver.caps.definitionProvider->type() == v:t_bool
53       lspserver.isDefinitionProvider = lspserver.caps.definitionProvider
54     else
55       lspserver.isDefinitionProvider = true
56     endif
57   else
58     lspserver.isDefinitionProvider = false
59   endif
60
61   # declarationProvider
62   if lspserver.caps->has_key('declarationProvider')
63     if lspserver.caps.declarationProvider->type() == v:t_bool
64       lspserver.isDeclarationProvider = lspserver.caps.declarationProvider
65     else
66       lspserver.isDeclarationProvider = true
67     endif
68   else
69     lspserver.isDeclarationProvider = false
70   endif
71
72   # typeDefinitionProvider
73   if lspserver.caps->has_key('typeDefinitionProvider')
74     if lspserver.caps.typeDefinitionProvider->type() == v:t_bool
75       lspserver.isTypeDefinitionProvider = lspserver.caps.typeDefinitionProvider
76     else
77       lspserver.isTypeDefinitionProvider = true
78     endif
79   else
80     lspserver.isTypeDefinitionProvider = false
81   endif
82
83   # implementationProvider
84   if lspserver.caps->has_key('implementationProvider')
85     if lspserver.caps.implementationProvider->type() == v:t_bool
86       lspserver.isImplementationProvider = lspserver.caps.implementationProvider
87     else
88       lspserver.isImplementationProvider = true
89     endif
90   else
91     lspserver.isImplementationProvider = false
92   endif
93
94   # signatureHelpProvider
95   if lspserver.caps->has_key('signatureHelpProvider')
96     lspserver.isSignatureHelpProvider = true
97   else
98     lspserver.isSignatureHelpProvider = false
99   endif
100
101   # hoverProvider
102   if lspserver.caps->has_key('hoverProvider')
103     if lspserver.caps.hoverProvider->type() == v:t_bool
104       lspserver.isHoverProvider = lspserver.caps.hoverProvider
105     else
106       lspserver.isHoverProvider = true
107     endif
108   else
109     lspserver.isHoverProvider = false
110   endif
111
112   # referencesProvider
113   if lspserver.caps->has_key('referencesProvider')
114     if lspserver.caps.referencesProvider->type() == v:t_bool
115       lspserver.isReferencesProvider = lspserver.caps.referencesProvider
116     else
117       lspserver.isReferencesProvider = true
118     endif
119   else
120     lspserver.isReferencesProvider = false
121   endif
122
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
128     else
129       lspserver.isDocumentHighlightProvider = true
130     endif
131   else
132     lspserver.isDocumentHighlightProvider = false
133   endif
134
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
140     else
141       lspserver.isDocumentSymbolProvider = true
142     endif
143   else
144     lspserver.isDocumentSymbolProvider = false
145   endif
146
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
152     else
153       lspserver.isDocumentFormattingProvider = true
154     endif
155   else
156     lspserver.isDocumentFormattingProvider = false
157   endif
158
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
164     else
165       lspserver.isCallHierarchyProvider = true
166     endif
167   else
168     lspserver.isCallHierarchyProvider = false
169   endif
170
171   # typeHierarchyProvider
172   if lspserver.caps->has_key('typeHierarchyProvider')
173     lspserver.isTypeHierarchyProvider = true
174   else
175     lspserver.isTypeHierarchyProvider = false
176   endif
177
178   # renameProvider
179   if lspserver.caps->has_key('renameProvider')
180     if lspserver.caps.renameProvider->type() == v:t_bool
181       lspserver.isRenameProvider = lspserver.caps.renameProvider
182     else
183       lspserver.isRenameProvider = true
184     endif
185   else
186     lspserver.isRenameProvider = false
187   endif
188
189   # codeActionProvider
190   if lspserver.caps->has_key('codeActionProvider')
191     if lspserver.caps.codeActionProvider->type() == v:t_bool
192       lspserver.isCodeActionProvider = lspserver.caps.codeActionProvider
193     else
194       lspserver.isCodeActionProvider = true
195     endif
196   else
197     lspserver.isCodeActionProvider = false
198   endif
199
200   # codeLensProvider
201   if lspserver.caps->has_key('codeLensProvider')
202     lspserver.isCodeLensProvider = true
203     if lspserver.caps.codeLensProvider->has_key('resolveProvider')
204       lspserver.isCodeLensResolveProvider = true
205     else
206       lspserver.isCodeLensResolveProvider = false
207     endif
208   else
209     lspserver.isCodeLensProvider = false
210   endif
211
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
217     else
218       lspserver.isWorkspaceSymbolProvider = true
219     endif
220   else
221     lspserver.isWorkspaceSymbolProvider = false
222   endif
223
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
229     else
230       lspserver.isSelectionRangeProvider = true
231     endif
232   else
233     lspserver.isSelectionRangeProvider = false
234   endif
235
236   # foldingRangeProvider
237   if lspserver.caps->has_key('foldingRangeProvider')
238     if lspserver.caps.foldingRangeProvider->type() == v:t_bool
239       lspserver.isFoldingRangeProvider = lspserver.caps.foldingRangeProvider
240     else
241       lspserver.isFoldingRangeProvider = true
242     endif
243   else
244     lspserver.isFoldingRangeProvider = false
245   endif
246
247   # inlayHintProvider
248   if lspserver.caps->has_key('inlayHintProvider')
249     if lspserver.caps.inlayHintProvider->type() == v:t_bool
250       lspserver.isInlayHintProvider = lspserver.caps.inlayHintProvider
251     else
252       lspserver.isInlayHintProvider = true
253     endif
254   else
255     lspserver.isInlayHintProvider = false
256   endif
257
258   # clangdInlayHintsProvider
259   if lspserver.caps->has_key('clangdInlayHintsProvider')
260     lspserver.isClangdInlayHintsProvider =
261                                         lspserver.caps.clangdInlayHintsProvider
262   else
263     lspserver.isClangdInlayHintsProvider = false
264   endif
265
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
276       # "save"
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
283         endif
284       endif
285       # "change"
286       if lspserver.caps.textDocumentSync->has_key('change')
287         lspserver.textDocumentSync = lspserver.caps.textDocumentSync.change
288       endif
289     endif
290   endif
291 enddef
292
293 # Return all the LSP client capabilities
294 export def GetClientCaps(): dict<any>
295   # client capabilities (ClientCapabilities)
296   var clientCaps: dict<any> = {
297     general: {
298       # Currently we always send character count as position offset,
299       # which meanas only utf-32 is supported.
300       # Adding utf-16 simply for good mesure, as I'm scared some servers will
301       # give up if they don't support utf-32 only.
302       positionEncodings: ['utf-32', 'utf-16']
303     },
304     textDocument: {
305       callHierarchy: {
306         dynamicRegistration: false
307       },
308       codeAction: {
309         dynamicRegistration: false,
310         codeActionLiteralSupport: {
311           codeActionKind: {
312             valueSet: ['', 'quickfix', 'refactor', 'refactor.extract',
313                         'refactor.inline', 'refactor.rewrite', 'source',
314                         'source.organizeImports']
315           }
316         },
317         isPreferredSupport: true,
318         disabledSupport: true
319       },
320       codeLens: {
321         dynamicRegistration: false
322       },
323       completion: {
324         dynamicRegistration: false,
325         completionItem: {
326           documentationFormat: ['markdown', 'plaintext'],
327           resolveSupport: {
328             properties: ['detail', 'documentation']
329           },
330           snippetSupport: opt.lspOptions.snippetSupport,
331           insertReplaceSupport: false
332         },
333         completionItemKind: {
334           valueSet: range(1, 25)
335         }
336       },
337       declaration: {
338         dynamicRegistration: false,
339         linkSupport: true
340       },
341       definition: {
342         dynamicRegistration: false,
343         linkSupport: true
344       },
345       documentHighlight: {
346         dynamicRegistration: false
347       },
348       documentSymbol: {
349         dynamicRegistration: false,
350         symbolKind: {
351           valueSet: range(1, 25)
352         },
353         hierarchicalDocumentSymbolSupport: true,
354         labelSupport: false
355       },
356       foldingRange: {
357         dynamicRegistration: false,
358         rangeLimit: 5000,
359         lineFoldingOnly: true,
360         foldingRangeKind: {
361           valueSet: ['comment', 'imports', 'region']
362         },
363         foldingRange: {
364           collapsedText: true
365         }
366       },
367       formatting: {
368         dynamicRegistration: false
369       },
370       hover: {
371         dynamicRegistration: false,
372         contentFormat: ['markdown', 'plaintext']
373       },
374       implementation: {
375         dynamicRegistration: false,
376         linkSupport: true
377       },
378       inlayHint: {
379         dynamicRegistration: false
380       },
381       publishDiagnostics: {
382         relatedInformation: false,
383         versionSupport: true,
384         codeDescriptionSupport: true,
385         dataSupport: true
386       },
387       rangeFormatting: {
388         dynamicRegistration: false
389       },
390       references: {
391         dynamicRegistration: false
392       },
393       rename: {
394         dynamicRegistration: false,
395         prepareSupport: false,
396       },
397       signatureHelp: {
398         dynamicRegistration: false,
399         signatureInformation: {
400           documentationFormat: ['markdown', 'plaintext'],
401           activeParameterSupport: true
402         }
403       },
404       synchronization: {
405         dynamicRegistration: false,
406         didSave: true,
407         willSave: false,
408         WillSaveWaitUntil: false
409       },
410       typeDefinition: {
411         dynamicRegistration: false,
412         linkSupport: true
413       },
414       typeHierarchy: {
415         dynamicRegistration: false,
416       }
417     },
418     window: {},
419     workspace: {
420       workspaceFolders: true,
421       applyEdit: true,
422       configuration: true,
423       symbol: {
424         dynamicRegistration: false
425       }
426     },
427     # This is the way clangd expects to be informated about supported encodings:
428     # https://clangd.llvm.org/extensions#utf-8-offsets
429     offsetEncoding: ['utf-32', 'utf-16']
430   }
431
432   # Vim patch 1629 is needed to properly encode/decode UTF-16 offsets
433   if has('patch-9.0.1629')
434     clientCaps.general.positionEncodings = ['utf-32', 'utf-16', 'utf-8']
435     clientCaps.offsetEncoding = ['utf-32', 'utf-16', 'utf-8']
436   endif
437
438   return clientCaps
439 enddef
440
441 # vim: tabstop=8 shiftwidth=2 softtabstop=2