diff options
Diffstat (limited to 'support/texlab/src/config.rs')
-rw-r--r-- | support/texlab/src/config.rs | 161 |
1 files changed, 74 insertions, 87 deletions
diff --git a/support/texlab/src/config.rs b/support/texlab/src/config.rs index 84de2268fa..5690bee091 100644 --- a/support/texlab/src/config.rs +++ b/support/texlab/src/config.rs @@ -1,103 +1,90 @@ -use crate::protocol::*; -use futures::lock::Mutex; -use log::{error, warn}; -use serde::de::DeserializeOwned; -use std::sync::Arc; +use std::sync::{Mutex, RwLock}; -#[derive(Debug)] -pub struct ConfigManager<C> { - client: Arc<C>, - client_capabilities: Arc<ClientCapabilities>, - options: Mutex<Options>, -} +use crossbeam_channel::Sender; +use log::{error, warn}; +use lsp_server::Message; +use lsp_types::{ + notification::{DidChangeConfiguration, Notification}, + request::{RegisterCapability, WorkspaceConfiguration}, + ClientCapabilities, ConfigurationItem, ConfigurationParams, Registration, RegistrationParams, +}; -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(), - } - } +use crate::{client::send_request, req_queue::ReqQueue, ClientCapabilitiesExt, Options}; - pub async fn get(&self) -> Options { - self.options.lock().await.clone() - } +pub fn register_config_capability( + req_queue: &Mutex<ReqQueue>, + sender: &Sender<Message>, + client_capabilities: &Mutex<ClientCapabilities>, +) { + let client_capabilities = client_capabilities.lock().unwrap(); + if !client_capabilities.has_pull_configuration_support() + && client_capabilities.has_push_configuration_support() + { + drop(client_capabilities); + let reg = Registration { + id: "pull-config".to_string(), + method: DidChangeConfiguration::METHOD.to_string(), + register_options: None, + }; - 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], - }; + let params = RegistrationParams { + registrations: vec![reg], + }; - if let Err(why) = self.client.register_capability(params).await { - error!( - "Failed to register \"workspace/didChangeConfiguration\": {}", - why.message - ); - } + if let Err(why) = send_request::<RegisterCapability>(&req_queue, &sender, params) { + error!( + "Failed to register \"{}\" notification: {}", + DidChangeConfiguration::METHOD, + why + ); } } +} - 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 fn pull_config( + req_queue: &Mutex<ReqQueue>, + sender: &Sender<Message>, + options: &RwLock<Options>, + client_capabilities: &ClientCapabilities, +) { + if !client_capabilities.has_pull_configuration_support() { + return; } - 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 params = ConfigurationParams { + items: vec![ConfigurationItem { + section: Some("texlab".to_string()), + scope_uri: None, + }], + }; - let new_options = Options { - latex: Some(latex), - bibtex: Some(bibtex), + match send_request::<WorkspaceConfiguration>(req_queue, sender, params) { + Ok(mut json) => { + let value = json.pop().expect("invalid configuration request"); + let new_options = match serde_json::from_value(value) { + Ok(new_options) => new_options, + Err(why) => { + warn!("Invalid configuration section \"texlab\": {}", why); + Options::default() + } }; - 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, - }], - }; + let mut options = options.write().unwrap(); + *options = new_options; + } + Err(why) => { + error!("Retrieving configuration failed: {}", why); + } + }; +} - 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() - } +pub fn push_config(options: &RwLock<Options>, config: serde_json::Value) { + match serde_json::from_value(config) { + Ok(new_options) => { + *options.write().unwrap() = new_options; } - } + Err(why) => { + error!("Invalid configuration: {}", why); + } + }; } |