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)] #[derive(Debug, Clone, Default)]
pub struct ClientCapabilities { pub struct ClientCapabilities {
pub status_notification: bool, pub status_notification: bool,
pub workspace_configuration: bool,
pub workspace_did_change_watched_files: bool,
} }
#[derive(Debug, Clone, Default, Deserialize)] #[derive(Debug, Clone, Default, Deserialize)]
@ -19,7 +21,10 @@ pub struct WorkspaceSettings {
pub enable: bool, pub enable: bool,
pub config: Option<String>, pub config: Option<String>,
pub import_map: Option<String>, pub import_map: Option<String>,
#[serde(default)]
pub lint: bool, pub lint: bool,
#[serde(default)]
pub unstable: bool, pub unstable: bool,
} }
@ -50,5 +55,14 @@ impl Config {
self.client_capabilities.status_notification = self.client_capabilities.status_notification =
get_bool("statusNotification"); 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,10 +460,18 @@ impl lspower::LanguageServer for LanguageServer {
.await; .await;
} }
if self
.config
.lock()
.unwrap()
.client_capabilities
.workspace_did_change_watched_files
{
// we are going to watch all the JSON files in the workspace, and the // 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 // notification handler will pick up any of the changes of those files we
// are interested in. // are interested in.
let watch_registration_options = DidChangeWatchedFilesRegistrationOptions { let watch_registration_options =
DidChangeWatchedFilesRegistrationOptions {
watchers: vec![FileSystemWatcher { watchers: vec![FileSystemWatcher {
glob_pattern: "**/*.json".to_string(), glob_pattern: "**/*.json".to_string(),
kind: Some(WatchKind::Change), kind: Some(WatchKind::Change),
@ -476,10 +484,12 @@ impl lspower::LanguageServer for LanguageServer {
serde_json::to_value(watch_registration_options).unwrap(), serde_json::to_value(watch_registration_options).unwrap(),
), ),
}; };
if let Err(err) = self.client.register_capability(vec![registration]).await if let Err(err) =
self.client.register_capability(vec![registration]).await
{ {
warn!("Client errored on capabilities.\n{}", err); warn!("Client errored on capabilities.\n{}", err);
} }
}
info!("Server ready."); info!("Server ready.");
} }
@ -575,20 +585,37 @@ impl lspower::LanguageServer for LanguageServer {
async fn did_change_configuration( async fn did_change_configuration(
&self, &self,
_params: DidChangeConfigurationParams, params: DidChangeConfigurationParams,
) { ) {
let res = self let config = if self
.config
.lock()
.unwrap()
.client_capabilities
.workspace_configuration
{
self
.client .client
.configuration(vec![ConfigurationItem { .configuration(vec![ConfigurationItem {
scope_uri: None, scope_uri: None,
section: Some("deno".to_string()), section: Some("deno".to_string()),
}]) }])
.await .await
.map(|vec| vec.get(0).cloned()); .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 { if let Some(config) = config {
Err(err) => error!("failed to fetch the extension settings {:?}", err),
Ok(Some(config)) => {
if let Err(err) = self.config.lock().unwrap().update(config) { if let Err(err) = self.config.lock().unwrap().update(config) {
error!("failed to update settings: {}", err); error!("failed to update settings: {}", err);
} }
@ -604,8 +631,8 @@ impl lspower::LanguageServer for LanguageServer {
.show_message(MessageType::Warning, err.to_string()) .show_message(MessageType::Warning, err.to_string())
.await; .await;
} }
} } else {
_ => error!("received empty extension settings from the client"), error!("received empty extension settings from the client");
} }
} }