diff options
author | Norbert Preining <norbert@preining.info> | 2020-05-28 03:03:21 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2020-05-28 03:03:21 +0000 |
commit | 745892fbddea56040139108277e728b53fd8fc11 (patch) | |
tree | 15e55e299b38fccdabce8364f1fbf4f02ef37994 /support/texlab/src/config.rs | |
parent | 195ca7e0c377d83455867bdd8e409d4e1cf024ea (diff) |
CTAN sync 202005280303
Diffstat (limited to 'support/texlab/src/config.rs')
-rw-r--r-- | support/texlab/src/config.rs | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/support/texlab/src/config.rs b/support/texlab/src/config.rs new file mode 100644 index 0000000000..84de2268fa --- /dev/null +++ b/support/texlab/src/config.rs @@ -0,0 +1,103 @@ +use crate::protocol::*; +use futures::lock::Mutex; +use log::{error, warn}; +use serde::de::DeserializeOwned; +use std::sync::Arc; + +#[derive(Debug)] +pub struct ConfigManager<C> { + client: Arc<C>, + client_capabilities: Arc<ClientCapabilities>, + options: Mutex<Options>, +} + +impl<C: LspClient + Send + Sync + 'static> ConfigManager<C> { + pub fn new(client: Arc<C>, client_capabilities: Arc<ClientCapabilities>) -> Self { + Self { + client, + client_capabilities, + options: Mutex::default(), + } + } + + pub async fn get(&self) -> Options { + self.options.lock().await.clone() + } + + pub async fn register(&self) { + if !self.client_capabilities.has_pull_configuration_support() + && self.client_capabilities.has_push_configuration_support() + { + let registration = Registration { + id: "pull-config".into(), + method: "workspace/didChangeConfiguration".into(), + register_options: None, + }; + let params = RegistrationParams { + registrations: vec![registration], + }; + + if let Err(why) = self.client.register_capability(params).await { + error!( + "Failed to register \"workspace/didChangeConfiguration\": {}", + why.message + ); + } + } + } + + pub async fn push(&self, options: serde_json::Value) { + match serde_json::from_value(options) { + Ok(options) => { + *self.options.lock().await = options; + } + Err(why) => { + error!("Invalid configuration: {}", why); + } + } + } + + pub async fn pull(&self) -> bool { + if self.client_capabilities.has_pull_configuration_support() { + let latex = self.pull_section("latex").await; + let bibtex = self.pull_section("bibtex").await; + + let new_options = Options { + latex: Some(latex), + bibtex: Some(bibtex), + }; + let mut old_options = self.options.lock().await; + let has_changed = *old_options != new_options; + *old_options = new_options; + has_changed + } else { + false + } + } + + async fn pull_section<T: DeserializeOwned + Default>(&self, section: &str) -> T { + let params = ConfigurationParams { + items: vec![ConfigurationItem { + section: Some(section.into()), + scope_uri: None, + }], + }; + + match self.client.configuration(params).await { + Ok(json) => match serde_json::from_value::<Vec<T>>(json) { + Ok(config) => config.into_iter().next().unwrap(), + Err(_) => { + warn!("Invalid configuration: {}", section); + T::default() + } + }, + Err(why) => { + error!( + "Retrieving configuration for {} failed: {}", + section, why.message + ); + T::default() + } + } + } +} |