]> Sergey Matveev's repositories - vim-lsp.git/blob - autoload/lsp/buffer.vim
Add an option (showDiagWithSign) to enable/disable placing signs on lines with diagno...
[vim-lsp.git] / autoload / lsp / buffer.vim
1 vim9script
2
3 # Functions for managing the per-buffer LSP server information
4
5 import './util.vim'
6
7 # A buffer can have one or more attached language servers.  The
8 # "bufnrToServers" Dict contains the list of language servers attached to a
9 # buffer. The buffer number is the key for the "bufnrToServers" Dict.  The
10 # value is the List of attached language servers.
11 var bufnrToServers: dict<list<dict<any>>> = {}
12
13 # Add "lspserver" to "bufnrToServers" map for buffer "bnr".
14 export def BufLspServerSet(bnr: number, lspserver: dict<any>)
15   if !bufnrToServers->has_key(bnr)
16     bufnrToServers[bnr] = []
17   endif
18
19   bufnrToServers[bnr]->add(lspserver)
20 enddef
21
22 # Remove "lspserver" from "bufnrToServers" map for buffer "bnr".
23 export def BufLspServerRemove(bnr: number, lspserver: dict<any>)
24   if !bufnrToServers->has_key(bnr)
25     return
26   endif
27
28   var servers: list<dict<any>> = bufnrToServers[bnr]
29   servers = servers->filter((key, srv) => srv.id != lspserver.id)
30
31   if servers->empty()
32     bufnrToServers->remove(bnr)
33   else
34     bufnrToServers[bnr] = servers
35   endif
36 enddef
37
38 var SupportedCheckFns = {
39   callHierarchy: (lspserver) => lspserver.isCallHierarchyProvider,
40   codeAction: (lspserver) => lspserver.isCodeActionProvider,
41   codeLens: (lspserver) => lspserver.isCodeLensProvider,
42   completion: (lspserver) => lspserver.isCompletionProvider,
43   declaration: (lspserver) => lspserver.isDeclarationProvider,
44   definition: (lspserver) => lspserver.isDefinitionProvider,
45   documentFormatting: (lspserver) => lspserver.isDocumentFormattingProvider,
46   documentHighlight: (lspserver) => lspserver.isDocumentHighlightProvider,
47   documentSymbol: (lspserver) => lspserver.isDocumentSymbolProvider,
48   foldingRange: (lspserver) => lspserver.isFoldingRangeProvider,
49   hover: (lspserver) => lspserver.isHoverProvider,
50   implementation: (lspserver) => lspserver.isImplementationProvider,
51   inlayHint: (lspserver) => lspserver.isInlayHintProvider,
52   references: (lspserver) => lspserver.isReferencesProvider,
53   rename: (lspserver) => lspserver.isRenameProvider,
54   selectionRange: (lspserver) => lspserver.isSelectionRangeProvider,
55   signatureHelp: (lspserver) => lspserver.isSignatureHelpProvider,
56   typeDefinition: (lspserver) => lspserver.isTypeDefinitionProvider,
57   typeHierarchy: (lspserver) => lspserver.isTypeHierarchyProvider,
58   workspaceSymbol: (lspserver) => lspserver.isWorkspaceSymbolProvider
59 }
60
61 # Returns the LSP server for the buffer "bnr".  If "feature" is specified,
62 # then returns the LSP server that provides the "feature".
63 # Returns an empty dict if the server is not found.
64 export def BufLspServerGet(bnr: number, feature: string = null_string): dict<any>
65   if !bufnrToServers->has_key(bnr)
66     return {}
67   endif
68
69   if bufnrToServers[bnr]->empty()
70     return {}
71   endif
72
73   if feature == null_string
74     return bufnrToServers[bnr][0]
75   endif
76
77   if !SupportedCheckFns->has_key(feature)
78     # If this happns it is a programming error, and should be fixed in the
79     # source code
80     :throw $'Error: ''{feature}'' is not a valid feature'
81   endif
82
83   var SupportedCheckFn = SupportedCheckFns[feature]
84
85   var possibleLSPs: list<dict<any>> = []
86
87   for lspserver in bufnrToServers[bnr]
88     if !SupportedCheckFn(lspserver)
89       continue
90     endif
91
92     possibleLSPs->add(lspserver)
93   endfor
94
95   if possibleLSPs->empty()
96     return {}
97   endif
98
99   # LSP server is configured to be a provider for "feature"
100   for lspserver in possibleLSPs
101     if lspserver.features->has_key(feature) && lspserver.features[feature]
102       return lspserver
103     endif
104   endfor
105
106   # Return the first LSP server that supports "feature" and doesn't have it
107   # disabled
108   for lspserver in possibleLSPs
109     if !lspserver.features->has_key(feature)
110       return lspserver
111     endif
112   endfor
113
114   return {}
115 enddef
116
117 # Returns the LSP server for the buffer "bnr" and with ID "id". Returns an empty
118 # dict if the server is not found.
119 export def BufLspServerGetById(bnr: number, id: number): dict<any>
120   if !bufnrToServers->has_key(bnr)
121     return {}
122   endif
123
124   for lspserver in bufnrToServers[bnr]
125     if lspserver.id == id
126       return lspserver
127     endif
128   endfor
129
130   return {}
131 enddef
132
133 # Returns the LSP servers for the buffer "bnr". Returns an empty list if the
134 # servers are not found.
135 export def BufLspServersGet(bnr: number): list<dict<any>>
136   if !bufnrToServers->has_key(bnr)
137     return []
138   endif
139
140   return bufnrToServers[bnr]
141 enddef
142
143 # Returns the LSP server for the current buffer with the optionally "feature".
144 # Returns an empty dict if the server is not found.
145 export def CurbufGetServer(feature: string = null_string): dict<any>
146   return BufLspServerGet(bufnr(), feature)
147 enddef
148
149 # Returns the LSP servers for the current buffer. Returns an empty list if the
150 # servers are not found.
151 export def CurbufGetServers(): list<dict<any>>
152   return BufLspServersGet(bufnr())
153 enddef
154
155 export def BufHasLspServer(bnr: number): bool
156   var lspserver = BufLspServerGet(bnr)
157
158   return !lspserver->empty()
159 enddef
160
161 # Returns the LSP server for the current buffer with the optinally "feature" if
162 # it is running and is ready.
163 # Returns an empty dict if the server is not found or is not ready.
164 export def CurbufGetServerChecked(feature: string = null_string): dict<any>
165   var fname: string = @%
166   if fname->empty()
167     return {}
168   endif
169
170   var lspserver: dict<any> = CurbufGetServer(feature)
171   if lspserver->empty()
172     if feature == null_string
173       util.ErrMsg($'Language server for "{&filetype}" file type is not found')
174     else
175       util.ErrMsg($'Language server for "{&filetype}" file type supporting "{feature}" feature is not found')
176     endif
177     return {}
178   endif
179   if !lspserver.running
180     util.ErrMsg($'Language server for "{&filetype}" file type is not running')
181     return {}
182   endif
183   if !lspserver.ready
184     util.ErrMsg($'Language server for "{&filetype}" file type is not ready')
185     return {}
186   endif
187
188   return lspserver
189 enddef
190
191 # vim: tabstop=8 shiftwidth=2 softtabstop=2