1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-21 23:04:45 -05:00

fix(lsp): Respect client capabilities for config and dynamic registration (#8865)

This commit is contained in:
Valentin Anger 2021-01-04 22:52:20 +01:00 committed by GitHub
parent 346b72ce70
commit 444eca80a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 89 additions and 48 deletions

View file

@ -11,6 +11,8 @@ use lspower::lsp_types;
#[derive(Debug, Clone, Default)]
pub struct ClientCapabilities {
pub status_notification: bool,
pub workspace_configuration: bool,
pub workspace_did_change_watched_files: bool,
}
#[derive(Debug, Clone, Default, Deserialize)]
@ -19,7 +21,10 @@ pub struct WorkspaceSettings {
pub enable: bool,
pub config: Option<String>,
pub import_map: Option<String>,
#[serde(default)]
pub lint: bool,
#[serde(default)]
pub unstable: bool,
}
@ -50,5 +55,14 @@ impl Config {
self.client_capabilities.status_notification =
get_bool("statusNotification");
}
if let Some(workspace) = &capabilities.workspace {
self.client_capabilities.workspace_configuration =
workspace.configuration.unwrap_or(false);
self.client_capabilities.workspace_did_change_watched_files = workspace
.did_change_watched_files
.and_then(|it| it.dynamic_registration)
.unwrap_or(false);
}
}
}

View file

@ -460,25 +460,35 @@ impl lspower::LanguageServer for LanguageServer {
.await;
}
// we are going to watch all the JSON files in the workspace, and the
// notification handler will pick up any of the changes of those files we
// are interested in.
let watch_registration_options = DidChangeWatchedFilesRegistrationOptions {
watchers: vec![FileSystemWatcher {
glob_pattern: "**/*.json".to_string(),
kind: Some(WatchKind::Change),
}],
};
let registration = Registration {
id: "workspace/didChangeWatchedFiles".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(
serde_json::to_value(watch_registration_options).unwrap(),
),
};
if let Err(err) = self.client.register_capability(vec![registration]).await
if self
.config
.lock()
.unwrap()
.client_capabilities
.workspace_did_change_watched_files
{
warn!("Client errored on capabilities.\n{}", err);
// we are going to watch all the JSON files in the workspace, and the
// notification handler will pick up any of the changes of those files we
// are interested in.
let watch_registration_options =
DidChangeWatchedFilesRegistrationOptions {
watchers: vec![FileSystemWatcher {
glob_pattern: "**/*.json".to_string(),
kind: Some(WatchKind::Change),
}],
};
let registration = Registration {
id: "workspace/didChangeWatchedFiles".to_string(),
method: "workspace/didChangeWatchedFiles".to_string(),
register_options: Some(
serde_json::to_value(watch_registration_options).unwrap(),
),
};
if let Err(err) =
self.client.register_capability(vec![registration]).await
{
warn!("Client errored on capabilities.\n{}", err);
}
}
info!("Server ready.");
@ -575,37 +585,54 @@ impl lspower::LanguageServer for LanguageServer {
async fn did_change_configuration(
&self,
_params: DidChangeConfigurationParams,
params: DidChangeConfigurationParams,
) {
let res = self
.client
.configuration(vec![ConfigurationItem {
scope_uri: None,
section: Some("deno".to_string()),
}])
.await
.map(|vec| vec.get(0).cloned());
let config = if self
.config
.lock()
.unwrap()
.client_capabilities
.workspace_configuration
{
self
.client
.configuration(vec![ConfigurationItem {
scope_uri: None,
section: Some("deno".to_string()),
}])
.await
.map(|vec| vec.get(0).cloned())
.unwrap_or_else(|err| {
error!("failed to fetch the extension settings {:?}", err);
None
})
} else {
params
.settings
.as_object()
.map(|settings| settings.get("deno"))
.flatten()
.cloned()
};
match res {
Err(err) => error!("failed to fetch the extension settings {:?}", err),
Ok(Some(config)) => {
if let Err(err) = self.config.lock().unwrap().update(config) {
error!("failed to update settings: {}", err);
}
if let Err(err) = self.update_import_map().await {
self
.client
.show_message(MessageType::Warning, err.to_string())
.await;
}
if let Err(err) = self.update_tsconfig().await {
self
.client
.show_message(MessageType::Warning, err.to_string())
.await;
}
if let Some(config) = config {
if let Err(err) = self.config.lock().unwrap().update(config) {
error!("failed to update settings: {}", err);
}
_ => error!("received empty extension settings from the client"),
if let Err(err) = self.update_import_map().await {
self
.client
.show_message(MessageType::Warning, err.to_string())
.await;
}
if let Err(err) = self.update_tsconfig().await {
self
.client
.show_message(MessageType::Warning, err.to_string())
.await;
}
} else {
error!("received empty extension settings from the client");
}
}
@ -1022,9 +1049,9 @@ impl LanguageServer {
let file_cache = self.file_cache.lock().unwrap();
Some(format!(
r#"# Deno Language Server Status
- Documents in memory: {}
"#,
file_cache.len()
))