Skip to content

Commit 1bed5d2

Browse files
request client config
1 parent 13f67f5 commit 1bed5d2

File tree

4 files changed

+75
-70
lines changed

4 files changed

+75
-70
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use serde::Deserialize;
22

33
// TODO: Check that the Opts are correct (existed in server.rs)
4-
#[derive(Deserialize)]
4+
#[derive(Deserialize, Debug)]
55
pub struct ClientConfigurationOptions {
66
pub db_connection_string: Option<String>,
77
}

crates/pg_lsp/src/server.rs

Lines changed: 67 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::fmt::format;
12
use std::sync::Arc;
23

34
use notification::ShowMessage;
@@ -66,40 +67,72 @@ impl LspServer {
6667
}
6768
}
6869

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+
}
7695
};
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+
}];
77104

78105
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 {
84107
Ok(json) => {
85108
// The client reponse fits the requested `ConfigurationParams.items`,
86109
// so the first value is what we're looking for.
87-
let relevant = json
88-
.into_iter()
110+
json.into_iter()
89111
.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.")
93113
}
94114
Err(why) => {
95115
let message = format!(
96116
"Unable to pull client options via workspace/configuration request: {}",
97117
why
98118
);
99119
self.client.log_message(MessageType::ERROR, message).await;
100-
None
120+
return;
101121
}
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+
};
103136
}
104137

105138
#[tracing::instrument(
@@ -185,7 +218,11 @@ impl LanguageServer for LspServer {
185218
self.client
186219
.show_message(MessageType::INFO, "Initialize Request received")
187220
.await;
221+
188222
let flags = ClientFlags::from_initialize_request_params(&params);
223+
224+
tracing::info!("flags: {:?}", flags);
225+
189226
self.client_capabilities.write().await.replace(flags);
190227

191228
Ok(InitializeResult {
@@ -220,6 +257,12 @@ impl LanguageServer for LspServer {
220257

221258
#[tracing::instrument(name = "initialized", skip(self, _params))]
222259
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+
223266
self.client
224267
.log_message(MessageType::INFO, "Postgres LSP Connected!")
225268
.await;
@@ -245,51 +288,11 @@ impl LanguageServer for LspServer {
245288
let capabilities = self.client_capabilities.read().await;
246289

247290
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+
};
293296
}
294297

295298
#[tracing::instrument(
@@ -332,13 +335,9 @@ impl LanguageServer for LspServer {
332335

333336
self.publish_diagnostics(uri).await;
334337

335-
// TODO: "Compute Now"
336338
let changed_urls = self.session.recompute_and_get_changed_files().await;
337339
for url in changed_urls {
338340
let url = Url::from_file_path(url.as_path()).expect("Expected absolute File Path");
339-
340-
tracing::info!("publishing diagnostics: {}", url);
341-
342341
self.publish_diagnostics(url).await;
343342
}
344343
}

crates/pg_lsp/src/session.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ impl Session {
4343
/// If the passed-in connection string is the same that we're already connected to, it's a noop.
4444
/// Otherwise, it'll first open a new connection, replace `Self`'s connection, and then close
4545
/// the old one.
46+
#[tracing::instrument(name = "Updating DB Connection", skip(self))]
4647
pub async fn change_db(&self, connection_string: String) -> anyhow::Result<()> {
4748
if self
4849
.db

editors/code/package.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,13 @@
8484
],
8585
"default": "off",
8686
"description": "Traces the communication between VS Code and the language server."
87+
},
88+
"pglsp.databaseUrl": {
89+
"type": "string",
90+
"default": "",
91+
"description": "Your Postgres Database URL"
8792
}
8893
}
8994
}
9095
}
91-
}
96+
}

0 commit comments

Comments
 (0)