diff options
Diffstat (limited to 'cli/lsp/config.rs')
-rw-r--r-- | cli/lsp/config.rs | 178 |
1 files changed, 47 insertions, 131 deletions
diff --git a/cli/lsp/config.rs b/cli/lsp/config.rs index 37558e1b7..1fef18bb3 100644 --- a/cli/lsp/config.rs +++ b/cli/lsp/config.rs @@ -226,6 +226,12 @@ enum ConfigRequest { Specifier(ModuleSpecifier, ModuleSpecifier), } +#[derive(Debug, Clone)] +pub struct SpecifierWithClientUri { + pub specifier: ModuleSpecifier, + pub client_uri: ModuleSpecifier, +} + #[derive(Debug, Default, Clone)] pub struct Settings { pub specifiers: @@ -236,149 +242,62 @@ pub struct Settings { #[derive(Debug)] pub struct Config { pub client_capabilities: ClientCapabilities, - settings: Arc<RwLock<Settings>>, - tx: mpsc::Sender<ConfigRequest>, + settings: Settings, pub workspace_folders: Option<Vec<WorkspaceFolder>>, } impl Config { - pub fn new(client: Client) -> Self { - let (tx, mut rx) = mpsc::channel::<ConfigRequest>(100); - let settings = Arc::new(RwLock::new(Settings::default())); - let settings_ref = settings.clone(); - - let _join_handle = thread::spawn(move || { - let runtime = create_basic_runtime(); - - runtime.block_on(async { - loop { - match rx.recv().await { - None => break, - Some(ConfigRequest::All) => { - let (specifier_uri_map, items): ( - Vec<(ModuleSpecifier, ModuleSpecifier)>, - Vec<lsp::ConfigurationItem>, - ) = { - let settings = settings_ref.read(); - ( - settings - .specifiers - .iter() - .map(|(s, (u, _))| (s.clone(), u.clone())) - .collect(), - settings - .specifiers - .iter() - .map(|(_, (uri, _))| lsp::ConfigurationItem { - scope_uri: Some(uri.clone()), - section: Some(SETTINGS_SECTION.to_string()), - }) - .collect(), - ) - }; - if let Ok(configs) = client.configuration(items).await { - let mut settings = settings_ref.write(); - for (i, value) in configs.into_iter().enumerate() { - match serde_json::from_value::<SpecifierSettings>(value) { - Ok(specifier_settings) => { - let (specifier, uri) = specifier_uri_map[i].clone(); - settings - .specifiers - .insert(specifier, (uri, specifier_settings)); - } - Err(err) => { - error!("Error converting specifier settings: {}", err); - } - } - } - } - } - Some(ConfigRequest::Specifier(specifier, uri)) => { - if settings_ref.read().specifiers.contains_key(&specifier) { - continue; - } - match client - .configuration(vec![lsp::ConfigurationItem { - scope_uri: Some(uri.clone()), - section: Some(SETTINGS_SECTION.to_string()), - }]) - .await - { - Ok(values) => { - if let Some(value) = values.first() { - match serde_json::from_value::<SpecifierSettings>(value.clone()) { - Ok(specifier_settings) => { - settings_ref - .write() - .specifiers - .insert(specifier, (uri, specifier_settings)); - } - Err(err) => { - error!("Error converting specifier settings ({}): {}", specifier, err); - } - } - } else { - error!("Expected the client to return a configuration item for specifier: {}", specifier); - } - }, - Err(err) => { - error!( - "Error retrieving settings for specifier ({}): {}", - specifier, - err, - ); - } - } - } - } - } - }) - }); - + pub fn new() -> Self { Self { client_capabilities: ClientCapabilities::default(), - settings, - tx, + settings: Default::default(), workspace_folders: None, } } pub fn get_workspace_settings(&self) -> WorkspaceSettings { - self.settings.read().workspace.clone() + self.settings.workspace.clone() } /// Set the workspace settings directly, which occurs during initialization /// and when the client does not support workspace configuration requests - pub fn set_workspace_settings(&self, value: Value) -> Result<(), AnyError> { + pub fn set_workspace_settings( + &mut self, + value: Value, + ) -> Result<(), AnyError> { let workspace_settings = serde_json::from_value(value)?; - self.settings.write().workspace = workspace_settings; + self.settings.workspace = workspace_settings; Ok(()) } pub fn snapshot(&self) -> Arc<ConfigSnapshot> { Arc::new(ConfigSnapshot { client_capabilities: self.client_capabilities.clone(), - settings: self.settings.read().clone(), + settings: self.settings.clone(), workspace_folders: self.workspace_folders.clone(), }) } + pub fn has_specifier_settings(&self, specifier: &ModuleSpecifier) -> bool { + self.settings.specifiers.contains_key(specifier) + } + pub fn specifier_enabled(&self, specifier: &ModuleSpecifier) -> bool { - let settings = self.settings.read(); - settings + self + .settings .specifiers .get(specifier) .map(|(_, s)| s.enable) - .unwrap_or_else(|| settings.workspace.enable) + .unwrap_or_else(|| self.settings.workspace.enable) } pub fn specifier_code_lens_test(&self, specifier: &ModuleSpecifier) -> bool { - let settings = self.settings.read(); - let value = settings + let value = self + .settings .specifiers .get(specifier) .map(|(_, s)| s.code_lens.test) - .unwrap_or_else(|| settings.workspace.code_lens.test); + .unwrap_or_else(|| self.settings.workspace.code_lens.test); value } @@ -416,26 +335,28 @@ impl Config { } } - /// Update all currently cached specifier settings - pub async fn update_all_settings(&self) -> Result<(), AnyError> { + pub fn get_specifiers_with_client_uris(&self) -> Vec<SpecifierWithClientUri> { self - .tx - .send(ConfigRequest::All) - .await - .map_err(|_| anyhow!("Error sending config update task.")) + .settings + .specifiers + .iter() + .map(|(s, (u, _))| SpecifierWithClientUri { + specifier: s.clone(), + client_uri: u.clone(), + }) + .collect::<Vec<_>>() } - /// Update a specific specifiers settings from the client. - pub async fn update_specifier_settings( - &self, - specifier: &ModuleSpecifier, - uri: &ModuleSpecifier, - ) -> Result<(), AnyError> { + pub fn set_specifier_settings( + &mut self, + specifier: ModuleSpecifier, + client_uri: ModuleSpecifier, + settings: SpecifierSettings, + ) { self - .tx - .send(ConfigRequest::Specifier(specifier.clone(), uri.clone())) - .await - .map_err(|_| anyhow!("Error sending config update task.")) + .settings + .specifiers + .insert(specifier, (client_uri, settings)); } } @@ -466,17 +387,12 @@ mod tests { } fn setup() -> Config { - let mut maybe_client: Option<Client> = None; - let (_service, _) = lspower::LspService::new(|client| { - maybe_client = Some(Client::from_lspower(client)); - MockLanguageServer::default() - }); - Config::new(maybe_client.unwrap()) + Config::new() } #[test] fn test_config_specifier_enabled() { - let config = setup(); + let mut config = setup(); let specifier = resolve_url("file:///a.ts").unwrap(); assert!(!config.specifier_enabled(&specifier)); config @@ -489,7 +405,7 @@ mod tests { #[test] fn test_set_workspace_settings_defaults() { - let config = setup(); + let mut config = setup(); config .set_workspace_settings(json!({})) .expect("could not update"); |