mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 07:14:47 -05:00
fix(lsp): Respect client capabilities for config and dynamic registration (#8865)
This commit is contained in:
parent
346b72ce70
commit
444eca80a9
2 changed files with 89 additions and 48 deletions
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -460,25 +460,35 @@ impl lspower::LanguageServer for LanguageServer {
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
// we are going to watch all the JSON files in the workspace, and the
|
if self
|
||||||
// notification handler will pick up any of the changes of those files we
|
.config
|
||||||
// are interested in.
|
.lock()
|
||||||
let watch_registration_options = DidChangeWatchedFilesRegistrationOptions {
|
.unwrap()
|
||||||
watchers: vec![FileSystemWatcher {
|
.client_capabilities
|
||||||
glob_pattern: "**/*.json".to_string(),
|
.workspace_did_change_watched_files
|
||||||
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);
|
// 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.");
|
info!("Server ready.");
|
||||||
|
@ -575,37 +585,54 @@ 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
|
||||||
.client
|
.config
|
||||||
.configuration(vec![ConfigurationItem {
|
.lock()
|
||||||
scope_uri: None,
|
.unwrap()
|
||||||
section: Some("deno".to_string()),
|
.client_capabilities
|
||||||
}])
|
.workspace_configuration
|
||||||
.await
|
{
|
||||||
.map(|vec| vec.get(0).cloned());
|
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 {
|
if let Some(config) = config {
|
||||||
Err(err) => error!("failed to fetch the extension settings {:?}", err),
|
if let Err(err) = self.config.lock().unwrap().update(config) {
|
||||||
Ok(Some(config)) => {
|
error!("failed to update settings: {}", err);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => 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();
|
let file_cache = self.file_cache.lock().unwrap();
|
||||||
Some(format!(
|
Some(format!(
|
||||||
r#"# Deno Language Server Status
|
r#"# Deno Language Server Status
|
||||||
|
|
||||||
- Documents in memory: {}
|
- Documents in memory: {}
|
||||||
|
|
||||||
"#,
|
"#,
|
||||||
file_cache.len()
|
file_cache.len()
|
||||||
))
|
))
|
||||||
|
|
Loading…
Reference in a new issue