diff options
Diffstat (limited to 'support/texlab/src/server.rs')
-rw-r--r-- | support/texlab/src/server.rs | 127 |
1 files changed, 86 insertions, 41 deletions
diff --git a/support/texlab/src/server.rs b/support/texlab/src/server.rs index 567d912435..bf0ef64261 100644 --- a/support/texlab/src/server.rs +++ b/support/texlab/src/server.rs @@ -1,4 +1,5 @@ mod dispatch; +pub mod options; mod query; use std::{ @@ -27,7 +28,8 @@ use crate::{ build::{self, BuildParams, BuildResult, BuildStatus}, completion::{self, builder::CompletionItemData}, definition, folding, formatting, forward_search, highlight, hover, inlay_hint, link, - reference, rename, symbol, workspace_command, + reference, rename, symbol, + workspace_command::{change_environment, clean, dep_graph}, }, normalize_uri, syntax::bibtex, @@ -35,9 +37,11 @@ use crate::{ self, capabilities::ClientCapabilitiesExt, components::COMPONENT_DATABASE, line_index_ext::LineIndexExt, }, - Db, Options, StartupOptions, + Config, Db, }; +use self::options::{Options, StartupOptions}; + #[derive(Debug)] enum InternalMessage { SetDistro(Distro), @@ -86,6 +90,45 @@ impl Server { }); } + fn run_and_request_with_db<R, S, Q>(&self, id: RequestId, query: Q) + where + R: Request, + S: Serialize, + Q: FnOnce(&dyn Db) -> Option<(S, R::Params)> + Send + 'static, + { + let client = self.client.clone(); + self.engine.fork(move |db| match query(db) { + Some((result, request_params)) => { + let response = lsp_server::Response::new_ok(id, result); + client.send_response(response).unwrap(); + client.send_request::<R>(request_params).unwrap(); + } + None => { + let response = lsp_server::Response::new_ok(id, Option::<S>::None); + client.send_response(response).unwrap(); + } + }); + } + + fn run_errorable<R, Q>(&self, id: RequestId, query: Q) + where + R: Serialize, + Q: FnOnce() -> Result<R> + Send + 'static, + { + let client = self.client.clone(); + self.pool.execute(move || match query() { + Ok(result) => { + let response = lsp_server::Response::new_ok(id, result); + client.send_response(response).unwrap(); + } + Err(why) => { + client + .send_error(id, ErrorCode::InternalError, why.to_string()) + .unwrap(); + } + }); + } + fn capabilities(&self) -> ServerCapabilities { ServerCapabilities { text_document_sync: Some(TextDocumentSyncCapability::Options( @@ -131,6 +174,7 @@ impl Server { commands: vec![ "texlab.cleanAuxiliary".into(), "texlab.cleanArtifacts".into(), + "texlab.changeEnvironment".into(), ], ..Default::default() }), @@ -150,10 +194,12 @@ impl Server { .with_durability(salsa::Durability::HIGH) .to(params.capabilities); - workspace - .set_client_info(db) + db::ServerContext::get(db) + .set_always_incomplete_completion_list(db) .with_durability(salsa::Durability::HIGH) - .to(params.client_info); + .to(params + .client_info + .map_or(false, |client| &client.name == "Visual Studio Code")); let root_dirs = params .workspace_folders @@ -260,7 +306,7 @@ impl Server { fn publish_diagnostics_with_delay(&mut self) { let db = self.engine.read(); let sender = self.internal_tx.clone(); - let delay = Workspace::get(db).options(db).diagnostics_delay.0; + let delay = db.config().diagnostics.delay; self.pool.execute(move || { std::thread::sleep(delay); sender.send(InternalMessage::Diagnostics).unwrap(); @@ -304,11 +350,10 @@ impl Server { fn update_options(&mut self, options: Options) { let db = self.engine.write(); - let workspace = Workspace::get(db); - workspace - .set_options(db) + db::ServerContext::get(db) + .set_config(db) .with_durability(salsa::Durability::MEDIUM) - .to(options); + .to(Config::from(options)); self.watcher.watch(db); } @@ -354,11 +399,7 @@ impl Server { self.update_workspace(); - if workspace - .options(self.engine.read()) - .chktex - .on_open_and_save - { + if self.engine.read().config().diagnostics.chktex.on_open { self.run_chktex(document); } @@ -379,12 +420,11 @@ impl Server { for change in params.content_changes { match change.range { Some(range) => { - let range = document.contents(db).line_index(db).offset_lsp_range(range); + let range = document.line_index(db).offset_lsp_range(range); document.edit(db, range, &change.text); } None => { document - .contents(db) .set_text(db) .with_durability(salsa::Durability::LOW) .to(change.text); @@ -399,7 +439,7 @@ impl Server { self.update_workspace(); - if workspace.options(self.engine.read()).chktex.on_edit { + if self.engine.read().config().diagnostics.chktex.on_edit { self.run_chktex(document); } @@ -412,7 +452,7 @@ impl Server { let db = self.engine.read(); let workspace = Workspace::get(db); - if workspace.options(db).build.on_save { + if db.config().build.on_save { self.build_internal(uri.clone(), |_| ())?; } @@ -420,7 +460,7 @@ impl Server { let db = self.engine.read(); if let Some(document) = workspace.lookup_uri(db, &uri) { - if workspace.options(db).chktex.on_open_and_save { + if db.config().diagnostics.chktex.on_save { self.run_chktex(document); } } @@ -550,7 +590,6 @@ impl Server { let workspace = Workspace::get(db); if let Some(document) = workspace.lookup_uri(db, &uri) { let position = document - .contents(db) .line_index(db) .offset_lsp(params.text_document_position_params.position); @@ -618,28 +657,34 @@ impl Server { } fn execute_command(&mut self, id: RequestId, params: ExecuteCommandParams) -> Result<()> { - let db = self.engine.read(); - match workspace_command::select(db, ¶ms.command, params.arguments) { - Ok(command) => { - let client = self.client.clone(); - self.pool.execute(move || { - match command.run() { - Ok(()) => { - client - .send_response(lsp_server::Response::new_ok(id, ())) - .unwrap(); - } - Err(why) => { - client - .send_error(id, ErrorCode::InternalError, why.to_string()) - .unwrap(); - } - }; + match params.command.as_str() { + "texlab.cleanAuxiliary" => { + let db = self.engine.read(); + let opt = clean::CleanOptions::Auxiliary; + let command = clean::CleanCommand::new(db, opt, params.arguments); + self.run_errorable(id, || command?.run()); + } + "texlab.cleanArtifacts" => { + let db = self.engine.read(); + let opt = clean::CleanOptions::Auxiliary; + let command = clean::CleanCommand::new(db, opt, params.arguments); + self.run_errorable(id, || command?.run()); + } + "texlab.changeEnvironment" => { + self.run_and_request_with_db::<ApplyWorkspaceEdit, _, _>(id, move |db| { + change_environment::change_environment(db, params.arguments) }); } - Err(why) => { + "texlab.showDependencyGraph" => { + self.run_with_db(id, move |db| dep_graph::show_dependency_graph(db).unwrap()); + } + _ => { self.client - .send_error(id, ErrorCode::InvalidParams, why.to_string()) + .send_error( + id, + ErrorCode::InvalidParams, + format!("Unknown workspace command: {}", params.command), + ) .unwrap(); } }; @@ -699,7 +744,7 @@ impl Server { } }; - let forward_search_after = Workspace::get(db).options(db).build.forward_search_after; + let forward_search_after = db.config().build.forward_search_after; let sender = self.internal_tx.clone(); self.pool.execute(move || { |