1
+ use std:: fmt:: format;
1
2
use std:: sync:: Arc ;
2
3
3
4
use notification:: ShowMessage ;
@@ -66,40 +67,72 @@ impl LspServer {
66
67
}
67
68
}
68
69
69
- #[ tracing:: instrument( name = "Requesting Configuration from Client" , skip( self ) ) ]
70
- async fn request_config_from_client ( & self ) -> Option < ClientConfigurationOptions > {
71
- let params = ConfigurationParams {
72
- items : vec ! [ ConfigurationItem {
73
- section: Some ( "pglsp" . to_string( ) ) ,
74
- scope_uri: None ,
75
- } ] ,
70
+ #[ tracing:: instrument( name = "Processing Config" , skip( self ) ) ]
71
+ async fn process_config ( & self , opts : Option < ClientConfigurationOptions > ) -> anyhow:: Result < ( ) > {
72
+ if opts
73
+ . as_ref ( )
74
+ . is_some_and ( |o| o. db_connection_string . is_some ( ) )
75
+ {
76
+ let conn_str = opts. unwrap ( ) . db_connection_string . unwrap ( ) ;
77
+ self . session . change_db ( conn_str) . await
78
+ } else {
79
+ Ok ( ( ) )
80
+ }
81
+ }
82
+
83
+ async fn parse_and_handle_config_from_client ( & self , value : serde_json:: Value ) {
84
+ let parsed = self . parse_config_from_client ( value) . await ;
85
+ match self . process_config ( parsed) . await {
86
+ Ok ( _) => { }
87
+ Err ( e) => {
88
+ self . client
89
+ . show_message (
90
+ MessageType :: ERROR ,
91
+ format ! ( "Unable to parse received config: {e:?}" ) ,
92
+ )
93
+ . await ;
94
+ }
76
95
} ;
96
+ }
97
+
98
+ #[ tracing:: instrument( name = "Requesting & Handling Configuration from Client" , skip( self ) ) ]
99
+ async fn request_and_handle_config_from_client ( & self ) {
100
+ let config_items = vec ! [ ConfigurationItem {
101
+ section: Some ( "pglsp" . to_string( ) ) ,
102
+ scope_uri: None ,
103
+ } ] ;
77
104
78
105
tracing:: info!( "sending workspace/configuration request" ) ;
79
- match self
80
- . client
81
- . send_request :: < request:: WorkspaceConfiguration > ( params)
82
- . await
83
- {
106
+ let config = match self . client . configuration ( config_items) . await {
84
107
Ok ( json) => {
85
108
// The client reponse fits the requested `ConfigurationParams.items`,
86
109
// so the first value is what we're looking for.
87
- let relevant = json
88
- . into_iter ( )
110
+ json. into_iter ( )
89
111
. next ( )
90
- . expect ( "workspace/configuration request did not yield expected response." ) ;
91
-
92
- self . parse_config_from_client ( relevant) . await
112
+ . expect ( "workspace/configuration request did not yield expected response." )
93
113
}
94
114
Err ( why) => {
95
115
let message = format ! (
96
116
"Unable to pull client options via workspace/configuration request: {}" ,
97
117
why
98
118
) ;
99
119
self . client . log_message ( MessageType :: ERROR , message) . await ;
100
- None
120
+ return ;
101
121
}
102
- }
122
+ } ;
123
+
124
+ let parsed = self . parse_config_from_client ( config) . await ;
125
+ match self . process_config ( parsed) . await {
126
+ Ok ( ( ) ) => { }
127
+ Err ( e) => {
128
+ self . client
129
+ . send_notification :: < ShowMessage > ( ShowMessageParams {
130
+ typ : MessageType :: ERROR ,
131
+ message : format ! ( "Unable to process config received from client: {e:?}" ) ,
132
+ } )
133
+ . await
134
+ }
135
+ } ;
103
136
}
104
137
105
138
#[ tracing:: instrument(
@@ -185,7 +218,11 @@ impl LanguageServer for LspServer {
185
218
self . client
186
219
. show_message ( MessageType :: INFO , "Initialize Request received" )
187
220
. await ;
221
+
188
222
let flags = ClientFlags :: from_initialize_request_params ( & params) ;
223
+
224
+ tracing:: info!( "flags: {:?}" , flags) ;
225
+
189
226
self . client_capabilities . write ( ) . await . replace ( flags) ;
190
227
191
228
Ok ( InitializeResult {
@@ -220,6 +257,12 @@ impl LanguageServer for LspServer {
220
257
221
258
#[ tracing:: instrument( name = "initialized" , skip( self , _params) ) ]
222
259
async fn initialized ( & self , _params : InitializedParams ) {
260
+ let capabilities = self . client_capabilities . read ( ) . await ;
261
+
262
+ if capabilities. as_ref ( ) . unwrap ( ) . supports_pull_opts {
263
+ self . request_and_handle_config_from_client ( ) . await ;
264
+ }
265
+
223
266
self . client
224
267
. log_message ( MessageType :: INFO , "Postgres LSP Connected!" )
225
268
. await ;
@@ -245,51 +288,11 @@ impl LanguageServer for LspServer {
245
288
let capabilities = self . client_capabilities . read ( ) . await ;
246
289
247
290
if capabilities. as_ref ( ) . unwrap ( ) . supports_pull_opts {
248
- let opts = self . request_config_from_client ( ) . await ;
249
- if opts
250
- . as_ref ( )
251
- . is_some_and ( |o| o. db_connection_string . is_some ( ) )
252
- {
253
- let conn_str = opts. unwrap ( ) . db_connection_string . unwrap ( ) ;
254
- match self . session . change_db ( conn_str) . await {
255
- Ok ( _) => { }
256
- Err ( err) => {
257
- self . client
258
- . show_message (
259
- MessageType :: ERROR ,
260
- format ! ( "Pulled Client Options but failed to set them: {}" , err) ,
261
- )
262
- . await
263
- }
264
- }
265
- return ;
266
- }
267
- }
268
-
269
- // if we couldn't pull settings from the client,
270
- // we'll try parsing the passed in params.
271
- let opts = self . parse_config_from_client ( params. settings ) . await ;
272
-
273
- if opts
274
- . as_ref ( )
275
- . is_some_and ( |o| o. db_connection_string . is_some ( ) )
276
- {
277
- let conn_str = opts. unwrap ( ) . db_connection_string . unwrap ( ) ;
278
- match self . session . change_db ( conn_str) . await {
279
- Ok ( _) => { }
280
- Err ( err) => {
281
- self . client
282
- . show_message (
283
- MessageType :: ERROR ,
284
- format ! (
285
- "Used Client Options from params but failed to set them: {}" ,
286
- err
287
- ) ,
288
- )
289
- . await
290
- }
291
- }
292
- }
291
+ self . request_and_handle_config_from_client ( ) . await
292
+ } else {
293
+ self . parse_and_handle_config_from_client ( params. settings )
294
+ . await
295
+ } ;
293
296
}
294
297
295
298
#[ tracing:: instrument(
@@ -332,13 +335,9 @@ impl LanguageServer for LspServer {
332
335
333
336
self . publish_diagnostics ( uri) . await ;
334
337
335
- // TODO: "Compute Now"
336
338
let changed_urls = self . session . recompute_and_get_changed_files ( ) . await ;
337
339
for url in changed_urls {
338
340
let url = Url :: from_file_path ( url. as_path ( ) ) . expect ( "Expected absolute File Path" ) ;
339
-
340
- tracing:: info!( "publishing diagnostics: {}" , url) ;
341
-
342
341
self . publish_diagnostics ( url) . await ;
343
342
}
344
343
}
0 commit comments