summaryrefslogtreecommitdiff
path: root/support/texlab/src/server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'support/texlab/src/server.rs')
-rw-r--r--support/texlab/src/server.rs127
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, &params.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 || {