mirror of
https://github.com/latex-lsp/texlab.git
synced 2025-08-04 18:58:31 +00:00
Add support for push-based configuration
This commit is contained in:
parent
eb315e5330
commit
b8b201deee
10 changed files with 312 additions and 84 deletions
|
@ -8,6 +8,10 @@ pub trait ClientCapabilitiesExt {
|
|||
fn has_work_done_progress_support(&self) -> bool;
|
||||
|
||||
fn has_hover_markdown_support(&self) -> bool;
|
||||
|
||||
fn has_pull_configuration_support(&self) -> bool;
|
||||
|
||||
fn has_push_configuration_support(&self) -> bool;
|
||||
}
|
||||
|
||||
impl ClientCapabilitiesExt for ClientCapabilities {
|
||||
|
@ -39,6 +43,18 @@ impl ClientCapabilitiesExt for ClientCapabilities {
|
|||
.filter(|formats| formats.contains(&MarkupKind::Markdown))
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn has_pull_configuration_support(&self) -> bool {
|
||||
self.workspace.as_ref().and_then(|cap| cap.configuration) == Some(true)
|
||||
}
|
||||
|
||||
fn has_push_configuration_support(&self) -> bool {
|
||||
self.workspace
|
||||
.as_ref()
|
||||
.and_then(|cap| cap.did_change_configuration)
|
||||
.and_then(|cap| cap.dynamic_registration)
|
||||
== Some(true)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -59,3 +59,24 @@ impl LatexBuildOptions {
|
|||
self.on_save.unwrap_or(false)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct LatexOptions {
|
||||
pub forward_search: Option<LatexForwardSearchOptions>,
|
||||
pub lint: Option<LatexLintOptions>,
|
||||
pub build: Option<LatexBuildOptions>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct BibtexOptions {
|
||||
pub formatting: Option<BibtexFormattingOptions>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Options {
|
||||
pub latex: Option<LatexOptions>,
|
||||
pub bibtex: Option<BibtexOptions>,
|
||||
}
|
||||
|
|
|
@ -11,12 +11,18 @@ async fn create_scenario(
|
|||
let scenario = Scenario::new("build", true).await;
|
||||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
|
||||
let options = LatexBuildOptions {
|
||||
executable: Some(executable.into()),
|
||||
args: None,
|
||||
on_save: Some(build_on_save),
|
||||
*scenario.client.options.lock().await = Options {
|
||||
latex: Some(LatexOptions {
|
||||
forward_search: None,
|
||||
lint: None,
|
||||
build: Some(LatexBuildOptions {
|
||||
executable: Some(executable.into()),
|
||||
args: None,
|
||||
on_save: Some(build_on_save),
|
||||
}),
|
||||
}),
|
||||
bibtex: None,
|
||||
};
|
||||
scenario.client.options.lock().await.latex_build = Some(options);
|
||||
|
||||
scenario.open(file).await;
|
||||
scenario
|
||||
|
|
|
@ -5,17 +5,10 @@ use serde::Serialize;
|
|||
use std::collections::HashMap;
|
||||
use texlab_protocol::*;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default)]
|
||||
pub struct MockLspClientOptions {
|
||||
pub bibtex_formatting: Option<BibtexFormattingOptions>,
|
||||
pub latex_lint: Option<LatexLintOptions>,
|
||||
pub latex_build: Option<LatexBuildOptions>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct MockLspClient {
|
||||
pub messages: Mutex<Vec<ShowMessageParams>>,
|
||||
pub options: Mutex<MockLspClientOptions>,
|
||||
pub options: Mutex<Options>,
|
||||
pub diagnostics_by_uri: Mutex<HashMap<Uri, Vec<Diagnostic>>>,
|
||||
pub log_messages: Mutex<Vec<LogMessageParams>>,
|
||||
}
|
||||
|
@ -52,10 +45,9 @@ impl LspClient for MockLspClient {
|
|||
|
||||
let options = self.options.lock().await;
|
||||
match params.items[0].section.as_ref().unwrap().as_ref() {
|
||||
"bibtex.formatting" => serialize(&options.bibtex_formatting),
|
||||
"latex.lint" => serialize(&options.latex_lint),
|
||||
"latex.build" => serialize(&options.latex_build),
|
||||
_ => panic!("Invalid language configuration!"),
|
||||
"latex" => serialize(&options.latex),
|
||||
"bibtex" => serialize(&options.bibtex),
|
||||
_ => panic!("invalid language configuration"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,12 @@ pub async fn run_bibtex(
|
|||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
scenario.open(file).await;
|
||||
{
|
||||
scenario.client.options.lock().await.bibtex_formatting = options;
|
||||
*scenario.client.options.lock().await = Options {
|
||||
bibtex: Some(BibtexOptions {
|
||||
formatting: options,
|
||||
}),
|
||||
latex: None,
|
||||
};
|
||||
}
|
||||
|
||||
let params = DocumentFormattingParams {
|
||||
|
|
|
@ -8,9 +8,11 @@ pub enum LintReason {
|
|||
Save,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
pub enum Action {
|
||||
RegisterCapabilities,
|
||||
LoadDistribution,
|
||||
UpdateConfiguration(serde_json::Value),
|
||||
DetectRoot(Uri),
|
||||
PublishDiagnostics,
|
||||
RunLinter(Uri, LintReason),
|
||||
|
|
129
src/config.rs
Normal file
129
src/config.rs
Normal file
|
@ -0,0 +1,129 @@
|
|||
use futures::lock::Mutex;
|
||||
use futures_boxed::boxed;
|
||||
use log::*;
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::sync::Arc;
|
||||
use texlab_protocol::*;
|
||||
|
||||
pub trait ConfigStrategy: Send + Sync {
|
||||
#[boxed]
|
||||
async fn get(&self) -> Options;
|
||||
|
||||
#[boxed()]
|
||||
async fn set(&self, settings: serde_json::Value);
|
||||
}
|
||||
|
||||
impl dyn ConfigStrategy {
|
||||
pub fn select<C: LspClient + Send + Sync + 'static>(
|
||||
capabilities: &ClientCapabilities,
|
||||
client: Arc<C>,
|
||||
) -> Box<Self> {
|
||||
if capabilities.has_pull_configuration_support() {
|
||||
Box::new(PullConfigStrategy::new(client))
|
||||
} else if capabilities.has_push_configuration_support() {
|
||||
Box::new(PushConfigStrategy::new())
|
||||
} else {
|
||||
Box::new(NoConfigStrategy::new())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct PullConfigStrategy<C> {
|
||||
client: Arc<C>,
|
||||
}
|
||||
|
||||
impl<C: LspClient> PullConfigStrategy<C> {
|
||||
pub fn new(client: Arc<C>) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
|
||||
async fn configuration<T>(&self, section: &'static str) -> T
|
||||
where
|
||||
T: DeserializeOwned + Default,
|
||||
{
|
||||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: LspClient + Send + Sync> ConfigStrategy for PullConfigStrategy<C> {
|
||||
#[boxed]
|
||||
async fn get(&self) -> Options {
|
||||
Options {
|
||||
latex: Some(self.configuration("latex").await),
|
||||
bibtex: Some(self.configuration("bibtex").await),
|
||||
}
|
||||
}
|
||||
|
||||
#[boxed]
|
||||
async fn set(&self, _settings: serde_json::Value) {}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct PushConfigStrategy {
|
||||
options: Mutex<Options>,
|
||||
}
|
||||
|
||||
impl PushConfigStrategy {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigStrategy for PushConfigStrategy {
|
||||
#[boxed]
|
||||
async fn get(&self) -> Options {
|
||||
let options = self.options.lock().await;
|
||||
options.clone()
|
||||
}
|
||||
|
||||
#[boxed()]
|
||||
async fn set(&self, settings: serde_json::Value) {
|
||||
let mut options = self.options.lock().await;
|
||||
match serde_json::from_value(settings) {
|
||||
Ok(settings) => *options = settings,
|
||||
Err(why) => warn!("Invalid configuration: {}", why),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
struct NoConfigStrategy;
|
||||
|
||||
impl NoConfigStrategy {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
}
|
||||
|
||||
impl ConfigStrategy for NoConfigStrategy {
|
||||
#[boxed]
|
||||
async fn get(&self) -> Options {
|
||||
Options::default()
|
||||
}
|
||||
|
||||
#[boxed()]
|
||||
async fn set(&self, _settings: serde_json::Value) {}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
pub mod action;
|
||||
pub mod build;
|
||||
pub mod config;
|
||||
pub mod definition;
|
||||
pub mod diagnostics;
|
||||
pub mod folding;
|
||||
|
|
125
src/server.rs
125
src/server.rs
|
@ -1,5 +1,6 @@
|
|||
use crate::action::{Action, ActionManager, LintReason};
|
||||
use crate::build::*;
|
||||
use crate::config::ConfigStrategy;
|
||||
use crate::definition::DefinitionProvider;
|
||||
use crate::diagnostics::DiagnosticsManager;
|
||||
use crate::folding::FoldingProvider;
|
||||
|
@ -15,7 +16,6 @@ use jsonrpc::server::{Middleware, Result};
|
|||
use jsonrpc_derive::{jsonrpc_method, jsonrpc_server};
|
||||
use log::*;
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
use serde::de::DeserializeOwned;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs;
|
||||
use std::future::Future;
|
||||
|
@ -34,6 +34,7 @@ pub struct LatexLspServer<C> {
|
|||
client: Arc<C>,
|
||||
client_capabilities: OnceCell<Arc<ClientCapabilities>>,
|
||||
distribution: Arc<Box<dyn Distribution>>,
|
||||
config_strategy: OnceCell<Box<dyn ConfigStrategy>>,
|
||||
build_manager: BuildManager<C>,
|
||||
workspace_manager: WorkspaceManager,
|
||||
action_manager: ActionManager,
|
||||
|
@ -57,6 +58,7 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
client: Arc::clone(&client),
|
||||
client_capabilities: OnceCell::new(),
|
||||
distribution: Arc::clone(&distribution),
|
||||
config_strategy: OnceCell::new(),
|
||||
build_manager: BuildManager::new(client),
|
||||
workspace_manager: WorkspaceManager::new(distribution),
|
||||
action_manager: ActionManager::default(),
|
||||
|
@ -97,6 +99,10 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
|
||||
#[jsonrpc_method("initialize", kind = "request")]
|
||||
pub async fn initialize(&self, params: InitializeParams) -> Result<InitializeResult> {
|
||||
let client = Arc::clone(&self.client);
|
||||
let config_strategy = ConfigStrategy::select(¶ms.capabilities, client);
|
||||
let _ = self.config_strategy.set(config_strategy);
|
||||
|
||||
self.client_capabilities
|
||||
.set(Arc::new(params.capabilities))
|
||||
.unwrap();
|
||||
|
@ -156,6 +162,7 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
|
||||
#[jsonrpc_method("initialized", kind = "notification")]
|
||||
pub fn initialized(&self, _params: InitializedParams) {
|
||||
self.action_manager.push(Action::RegisterCapabilities);
|
||||
self.action_manager.push(Action::PublishDiagnostics);
|
||||
self.action_manager.push(Action::LoadDistribution);
|
||||
}
|
||||
|
@ -209,6 +216,12 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
#[jsonrpc_method("textDocument/didClose", kind = "notification")]
|
||||
pub fn did_close(&self, _params: DidCloseTextDocumentParams) {}
|
||||
|
||||
#[jsonrpc_method("workspace/didChangeConfiguration", kind = "notification")]
|
||||
pub fn did_change_configuration(&self, params: DidChangeConfigurationParams) {
|
||||
self.action_manager
|
||||
.push(Action::UpdateConfiguration(params.settings));
|
||||
}
|
||||
|
||||
#[jsonrpc_method("window/workDoneProgress/cancel", kind = "notification")]
|
||||
pub fn work_done_progress_cancel(&self, params: WorkDoneProgressCancelParams) {
|
||||
self.action_manager.push(Action::CancelBuild(params.token));
|
||||
|
@ -334,12 +347,17 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
let request = self.make_feature_request(params.text_document.as_uri(), params)?;
|
||||
let mut edits = Vec::new();
|
||||
if let SyntaxTree::Bibtex(tree) = &request.document().tree {
|
||||
let options = self
|
||||
.configuration()
|
||||
.await
|
||||
.bibtex
|
||||
.and_then(|opts| opts.formatting)
|
||||
.unwrap_or_default();
|
||||
|
||||
let params = BibtexFormattingParams {
|
||||
tab_size: request.params.options.tab_size as usize,
|
||||
insert_spaces: request.params.options.insert_spaces,
|
||||
options: self
|
||||
.configuration::<BibtexFormattingOptions>("bibtex.formatting")
|
||||
.await,
|
||||
options,
|
||||
};
|
||||
|
||||
for declaration in &tree.root.children {
|
||||
|
@ -384,7 +402,12 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
#[jsonrpc_method("textDocument/build", kind = "request")]
|
||||
pub async fn build(&self, params: BuildParams) -> Result<BuildResult> {
|
||||
let request = self.make_feature_request(params.text_document.as_uri(), params)?;
|
||||
let options = self.configuration::<LatexBuildOptions>("latex.build").await;
|
||||
let options = self
|
||||
.configuration()
|
||||
.await
|
||||
.latex
|
||||
.and_then(|opts| opts.build)
|
||||
.unwrap_or_default();
|
||||
let result = self.build_manager.build(request, options).await;
|
||||
Ok(result)
|
||||
}
|
||||
|
@ -396,8 +419,11 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
) -> Result<ForwardSearchResult> {
|
||||
let request = self.make_feature_request(params.text_document.as_uri(), params)?;
|
||||
let options = self
|
||||
.configuration::<LatexForwardSearchOptions>("latex.forwardSearch")
|
||||
.await;
|
||||
.configuration()
|
||||
.await
|
||||
.latex
|
||||
.and_then(|opts| opts.forward_search)
|
||||
.unwrap_or_default();
|
||||
|
||||
match request.document().uri.to_file_path() {
|
||||
Ok(tex_file) => {
|
||||
|
@ -416,43 +442,12 @@ impl<C: LspClient + Send + Sync + 'static> LatexLspServer<C> {
|
|||
}
|
||||
}
|
||||
|
||||
async fn configuration<T>(&self, section: &'static str) -> T
|
||||
where
|
||||
T: DeserializeOwned + Default,
|
||||
{
|
||||
if !self
|
||||
.client_capabilities
|
||||
async fn configuration(&self) -> Options {
|
||||
self.config_strategy
|
||||
.get()
|
||||
.and_then(|cap| cap.workspace.as_ref())
|
||||
.and_then(|cap| cap.configuration)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return T::default();
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
.expect("initialize needs to be called before using the server")
|
||||
.get()
|
||||
.await
|
||||
}
|
||||
|
||||
fn make_feature_request<P>(&self, uri: Uri, params: P) -> Result<FeatureRequest<P>> {
|
||||
|
@ -581,6 +576,25 @@ impl<C: LspClient + Send + Sync + 'static> Middleware for LatexLspServer<C> {
|
|||
self.update_build_diagnostics().await;
|
||||
for action in self.action_manager.take() {
|
||||
match action {
|
||||
Action::RegisterCapabilities => {
|
||||
let capabilities = self.client_capabilities.get().unwrap();
|
||||
if !capabilities.has_pull_configuration_support()
|
||||
&& 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],
|
||||
};
|
||||
self.client
|
||||
.register_capability(params)
|
||||
.await
|
||||
.expect("failed to register \"workspace/didChangeConfiguration\"");
|
||||
}
|
||||
}
|
||||
Action::LoadDistribution => {
|
||||
info!("Detected TeX distribution: {:?}", self.distribution.kind());
|
||||
if self.distribution.kind() == DistributionKind::Unknown {
|
||||
|
@ -612,6 +626,9 @@ impl<C: LspClient + Send + Sync + 'static> Middleware for LatexLspServer<C> {
|
|||
self.client.show_message(params).await;
|
||||
};
|
||||
}
|
||||
Action::UpdateConfiguration(settings) => {
|
||||
self.config_strategy.get().unwrap().set(settings).await;
|
||||
}
|
||||
Action::DetectRoot(uri) => {
|
||||
self.detect_root(uri).await;
|
||||
}
|
||||
|
@ -631,10 +648,16 @@ impl<C: LspClient + Send + Sync + 'static> Middleware for LatexLspServer<C> {
|
|||
}
|
||||
}
|
||||
Action::RunLinter(uri, reason) => {
|
||||
let config: LatexLintOptions = self.configuration("latex.lint").await;
|
||||
let options = self
|
||||
.configuration()
|
||||
.await
|
||||
.latex
|
||||
.and_then(|opts| opts.lint)
|
||||
.unwrap_or_default();
|
||||
|
||||
let should_lint = match reason {
|
||||
LintReason::Change => config.on_change(),
|
||||
LintReason::Save => config.on_save(),
|
||||
LintReason::Change => options.on_change(),
|
||||
LintReason::Save => options.on_save(),
|
||||
};
|
||||
if should_lint {
|
||||
let workspace = self.workspace_manager.get();
|
||||
|
@ -647,8 +670,14 @@ impl<C: LspClient + Send + Sync + 'static> Middleware for LatexLspServer<C> {
|
|||
}
|
||||
}
|
||||
Action::Build(uri) => {
|
||||
let config: LatexBuildOptions = self.configuration("latex.build").await;
|
||||
if config.on_save() {
|
||||
let options = self
|
||||
.configuration()
|
||||
.await
|
||||
.latex
|
||||
.and_then(|opts| opts.build)
|
||||
.unwrap_or_default();
|
||||
|
||||
if options.on_save() {
|
||||
let text_document = TextDocumentIdentifier::new(uri.into());
|
||||
self.build(BuildParams { text_document }).await.unwrap();
|
||||
}
|
||||
|
|
|
@ -7,10 +7,17 @@ async fn disabled() {
|
|||
let scenario = Scenario::new("diagnostics/latex", true).await;
|
||||
match scenario.distribution.kind() {
|
||||
Texlive | Miktex => {
|
||||
scenario.client.options.lock().await.latex_lint = Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(false),
|
||||
});
|
||||
*scenario.client.options.lock().await = Options {
|
||||
latex: Some(LatexOptions {
|
||||
forward_search: None,
|
||||
lint: Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(false),
|
||||
}),
|
||||
build: None,
|
||||
}),
|
||||
bibtex: None,
|
||||
};
|
||||
|
||||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
scenario.open("disabled.tex").await;
|
||||
|
@ -28,10 +35,17 @@ async fn on_open() {
|
|||
let scenario = Scenario::new("diagnostics/latex", true).await;
|
||||
match scenario.distribution.kind() {
|
||||
Texlive | Miktex => {
|
||||
scenario.client.options.lock().await.latex_lint = Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(true),
|
||||
});
|
||||
*scenario.client.options.lock().await = Options {
|
||||
latex: Some(LatexOptions {
|
||||
forward_search: None,
|
||||
lint: Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(true),
|
||||
}),
|
||||
build: None,
|
||||
}),
|
||||
bibtex: None,
|
||||
};
|
||||
|
||||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
scenario.open("on_open.tex").await;
|
||||
|
@ -51,10 +65,17 @@ async fn on_save() {
|
|||
let scenario = Scenario::new("diagnostics/latex", true).await;
|
||||
match scenario.distribution.kind() {
|
||||
Texlive | Miktex => {
|
||||
scenario.client.options.lock().await.latex_lint = Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(true),
|
||||
});
|
||||
*scenario.client.options.lock().await = Options {
|
||||
latex: Some(LatexOptions {
|
||||
forward_search: None,
|
||||
lint: Some(LatexLintOptions {
|
||||
on_change: Some(false),
|
||||
on_save: Some(true),
|
||||
}),
|
||||
build: None,
|
||||
}),
|
||||
bibtex: None,
|
||||
};
|
||||
|
||||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
scenario.open("on_save.tex").await;
|
||||
|
@ -99,11 +120,17 @@ async fn on_change() {
|
|||
let scenario = Scenario::new("diagnostics/latex", true).await;
|
||||
match scenario.distribution.kind() {
|
||||
Texlive | Miktex => {
|
||||
scenario.client.options.lock().await.latex_lint = Some(LatexLintOptions {
|
||||
on_change: Some(true),
|
||||
on_save: Some(true),
|
||||
});
|
||||
|
||||
*scenario.client.options.lock().await = Options {
|
||||
latex: Some(LatexOptions {
|
||||
forward_search: None,
|
||||
lint: Some(LatexLintOptions {
|
||||
on_change: Some(true),
|
||||
on_save: Some(true),
|
||||
}),
|
||||
build: None,
|
||||
}),
|
||||
bibtex: None,
|
||||
};
|
||||
scenario.initialize(&CLIENT_FULL_CAPABILITIES).await;
|
||||
scenario.open("on_change.tex").await;
|
||||
let uri = scenario.uri("on_change.tex");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue