1
- use std:: path:: PathBuf ;
1
+ use std:: { ops :: Deref , path:: PathBuf } ;
2
2
3
3
use lsp_types:: Url ;
4
4
use rustc_hash:: FxHashMap ;
@@ -7,6 +7,24 @@ use serde::Deserialize;
7
7
/// Maps a workspace URI to its associated client settings. Used during server initialization.
8
8
pub ( crate ) type WorkspaceSettingsMap = FxHashMap < Url , ClientSettings > ;
9
9
10
+ // TODO(dhruvmanila): We need to mirror the "python.*" namespace on the server side but ideally it
11
+ // would be useful to instead use `workspace/didChangeConfiguration` notification instead. This
12
+ // would be then used to get all settings and not just the ones in "python.*".
13
+
14
+ #[ derive( Debug , Deserialize , Default ) ]
15
+ #[ cfg_attr( test, derive( PartialEq , Eq ) ) ]
16
+ #[ serde( rename_all = "camelCase" ) ]
17
+ struct Python {
18
+ ty : Option < Ty > ,
19
+ }
20
+
21
+ #[ derive( Debug , Deserialize , Default ) ]
22
+ #[ cfg_attr( test, derive( PartialEq , Eq ) ) ]
23
+ #[ serde( rename_all = "camelCase" ) ]
24
+ struct Ty {
25
+ disable_language_services : Option < bool > ,
26
+ }
27
+
10
28
#[ derive( Debug , Deserialize , Default ) ]
11
29
#[ cfg_attr( test, derive( PartialEq , Eq ) ) ]
12
30
#[ serde( rename_all = "camelCase" ) ]
@@ -36,6 +54,11 @@ impl Experimental {
36
54
#[ serde( rename_all = "camelCase" ) ]
37
55
pub struct ClientSettings {
38
56
pub ( crate ) experimental : Option < Experimental > ,
57
+
58
+ /// Settings under the `python.*` namespace in VS Code that are useful for the ty language
59
+ /// server.
60
+ python : Option < Python > ,
61
+
39
62
// These settings are only needed for tracing, and are only read from the global configuration.
40
63
// These will not be in the resolved settings.
41
64
#[ serde( flatten) ]
@@ -133,3 +156,66 @@ impl Default for InitializationOptions {
133
156
}
134
157
}
135
158
}
159
+
160
+ /// Resolved client settings for a specific document. These settings are meant to be
161
+ /// used directly by the server, and are *not* a 1:1 representation with how the client
162
+ /// sends them.
163
+ #[ derive( Clone , Debug ) ]
164
+ #[ cfg_attr( test, derive( PartialEq , Eq ) ) ]
165
+ pub ( crate ) struct ResolvedClientSettings {
166
+ disable_language_services : bool ,
167
+ }
168
+
169
+ impl ResolvedClientSettings {
170
+ pub ( crate ) fn is_language_services_disabled ( & self ) -> bool {
171
+ self . disable_language_services
172
+ }
173
+
174
+ /// Resolves global settings only.
175
+ pub ( super ) fn global ( global_settings : & ClientSettings ) -> Self {
176
+ Self :: new_impl ( & [ global_settings] )
177
+ }
178
+
179
+ fn new_impl ( all_settings : & [ & ClientSettings ] ) -> Self {
180
+ Self {
181
+ disable_language_services : Self :: resolve_or (
182
+ all_settings,
183
+ |settings| {
184
+ settings
185
+ . python
186
+ . as_ref ( ) ?
187
+ . ty
188
+ . as_ref ( ) ?
189
+ . disable_language_services
190
+ } ,
191
+ false ,
192
+ ) ,
193
+ }
194
+ }
195
+
196
+ /// Attempts to resolve a setting using a list of available client settings as sources.
197
+ /// Client settings that come earlier in the list take priority. `default` will be returned
198
+ /// if none of the settings specify the requested setting.
199
+ ///
200
+ /// Use [`ResolvedClientSettings::resolve_optional`] if the setting should be optional instead
201
+ /// of having a default value.
202
+ fn resolve_or < T > (
203
+ all_settings : & [ & ClientSettings ] ,
204
+ get : impl Fn ( & ClientSettings ) -> Option < T > ,
205
+ default : T ,
206
+ ) -> T {
207
+ Self :: resolve_optional ( all_settings, get) . unwrap_or ( default)
208
+ }
209
+
210
+ /// Attempts to resolve a setting using a list of available client settings as sources.
211
+ /// Client settings that come earlier in the list take priority. This function is for fields
212
+ /// that do not have a default value and should be left unset.
213
+ ///
214
+ /// Use [`ResolvedClientSettings::resolve_or`] for settings that should have default values.
215
+ fn resolve_optional < T > (
216
+ all_settings : & [ & ClientSettings ] ,
217
+ get : impl FnMut ( & ClientSettings ) -> Option < T > ,
218
+ ) -> Option < T > {
219
+ all_settings. iter ( ) . map ( Deref :: deref) . find_map ( get)
220
+ }
221
+ }
0 commit comments