summaryrefslogtreecommitdiff
path: root/support/texlab/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/config.rs')
-rw-r--r--support/texlab/src/config.rs161
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);
+ }
+ };
}