feat(els): stop autocheck if autosave is enabled

This commit is contained in:
Shunsuke Shibayama 2023-08-22 00:00:30 +09:00
parent bcd4e4deb7
commit 499ecb5d40
2 changed files with 58 additions and 14 deletions

View file

@ -19,9 +19,11 @@ use lsp_types::{
}; };
use serde_json::json; use serde_json::json;
use crate::_log;
use crate::diff::{ASTDiff, HIRDiff}; use crate::diff::{ASTDiff, HIRDiff};
use crate::server::{ use crate::server::{
send, send_log, AnalysisResult, DefaultFeatures, ELSResult, Server, HEALTH_CHECKER_ID, send, send_log, AnalysisResult, DefaultFeatures, ELSResult, Server, ASK_AUTO_SAVE_ID,
HEALTH_CHECKER_ID,
}; };
use crate::util::{self, NormalizedUrl}; use crate::util::{self, NormalizedUrl};
@ -204,7 +206,8 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
} }
let params = PublishDiagnosticsParams::new(uri, diagnostics, None); let params = PublishDiagnosticsParams::new(uri, diagnostics, None);
if self if self
.client_capas .init_params
.capabilities
.text_document .text_document
.as_ref() .as_ref()
.map(|doc| doc.publish_diagnostics.is_some()) .map(|doc| doc.publish_diagnostics.is_some())
@ -229,6 +232,25 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
move || { move || {
let mut file_vers = Dict::<NormalizedUrl, i32>::new(); let mut file_vers = Dict::<NormalizedUrl, i32>::new();
loop { loop {
if _self
.client_answers
.borrow()
.get(&ASK_AUTO_SAVE_ID)
.is_none()
{
_self.ask_auto_save().unwrap();
} else if _self
.client_answers
.borrow()
.get(&ASK_AUTO_SAVE_ID)
.is_some_and(|val| {
val["result"].as_array().and_then(|a| a[0].as_str())
== Some("afterDelay")
})
{
_log!("Auto saving is enabled");
break;
}
for uri in _self.file_cache.entries() { for uri in _self.file_cache.entries() {
let Some(latest_ver) = _self.file_cache.get_ver(&uri) else { let Some(latest_ver) = _self.file_cache.get_ver(&uri) else {
continue; continue;

View file

@ -32,12 +32,13 @@ use lsp_types::request::{
WillRenameFiles, WillRenameFiles,
}; };
use lsp_types::{ use lsp_types::{
ClientCapabilities, CodeActionKind, CodeActionOptions, CodeActionProviderCapability, CodeActionKind, CodeActionOptions, CodeActionProviderCapability, CodeLensOptions,
CodeLensOptions, CompletionOptions, DidChangeTextDocumentParams, DidOpenTextDocumentParams, CompletionOptions, ConfigurationItem, ConfigurationParams, DidChangeTextDocumentParams,
ExecuteCommandOptions, HoverProviderCapability, InitializeResult, InlayHintOptions, DidOpenTextDocumentParams, ExecuteCommandOptions, HoverProviderCapability, InitializeParams,
InlayHintServerCapabilities, OneOf, Position, SemanticTokenType, SemanticTokensFullOptions, InitializeResult, InlayHintOptions, InlayHintServerCapabilities, OneOf, Position,
SemanticTokensLegend, SemanticTokensOptions, SemanticTokensServerCapabilities, SemanticTokenType, SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions,
ServerCapabilities, SignatureHelpOptions, WorkDoneProgressOptions, SemanticTokensServerCapabilities, ServerCapabilities, SignatureHelpOptions,
WorkDoneProgressOptions,
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -52,6 +53,7 @@ use crate::message::{ErrorMessage, LSPResult, LogMessage, ShowMessage};
use crate::util::{self, NormalizedUrl}; use crate::util::{self, NormalizedUrl};
pub const HEALTH_CHECKER_ID: i64 = 10000; pub const HEALTH_CHECKER_ID: i64 = 10000;
pub const ASK_AUTO_SAVE_ID: i64 = 10001;
pub type ELSResult<T> = Result<T, Box<dyn std::error::Error>>; pub type ELSResult<T> = Result<T, Box<dyn std::error::Error>>;
@ -312,7 +314,8 @@ pub struct Server<Checker: BuildRunnable = HIRBuilder, Parser: Parsable = Simple
pub(crate) cfg: ErgConfig, pub(crate) cfg: ErgConfig,
pub(crate) home: PathBuf, pub(crate) home: PathBuf,
pub(crate) erg_path: PathBuf, pub(crate) erg_path: PathBuf,
pub(crate) client_capas: ClientCapabilities, pub(crate) init_params: InitializeParams,
pub(crate) client_answers: Shared<Dict<i64, Value>>,
pub(crate) disabled_features: Vec<DefaultFeatures>, pub(crate) disabled_features: Vec<DefaultFeatures>,
pub(crate) opt_features: Vec<OptionalFeatures>, pub(crate) opt_features: Vec<OptionalFeatures>,
pub(crate) file_cache: FileCache, pub(crate) file_cache: FileCache,
@ -332,7 +335,8 @@ impl<C: BuildRunnable, P: Parsable> Clone for Server<C, P> {
cfg: self.cfg.clone(), cfg: self.cfg.clone(),
home: self.home.clone(), home: self.home.clone(),
erg_path: self.erg_path.clone(), erg_path: self.erg_path.clone(),
client_capas: self.client_capas.clone(), init_params: self.init_params.clone(),
client_answers: self.client_answers.clone(),
disabled_features: self.disabled_features.clone(), disabled_features: self.disabled_features.clone(),
opt_features: self.opt_features.clone(), opt_features: self.opt_features.clone(),
file_cache: self.file_cache.clone(), file_cache: self.file_cache.clone(),
@ -354,7 +358,8 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
cfg, cfg,
home: normalize_path(std::env::current_dir().unwrap_or_default()), home: normalize_path(std::env::current_dir().unwrap_or_default()),
erg_path: erg_path().clone(), // already normalized erg_path: erg_path().clone(), // already normalized
client_capas: ClientCapabilities::default(), init_params: InitializeParams::default(),
client_answers: Shared::new(Dict::new()),
disabled_features: vec![], disabled_features: vec![],
opt_features: vec![], opt_features: vec![],
file_cache: FileCache::new(), file_cache: FileCache::new(),
@ -390,7 +395,7 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
send_log("initializing ELS")?; send_log("initializing ELS")?;
// #[allow(clippy::collapsible_if)] // #[allow(clippy::collapsible_if)]
if msg.get("params").is_some() && msg["params"].get("capabilities").is_some() { if msg.get("params").is_some() && msg["params"].get("capabilities").is_some() {
self.client_capas = ClientCapabilities::deserialize(&msg["params"]["capabilities"])?; self.init_params = InitializeParams::deserialize(&msg["params"])?;
// send_log(format!("set client capabilities: {:?}", self.client_capas))?; // send_log(format!("set client capabilities: {:?}", self.client_capas))?;
} }
let mut args = self.cfg.runtime_args.iter(); let mut args = self.cfg.runtime_args.iter();
@ -503,6 +508,21 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
capabilities capabilities
} }
pub(crate) fn ask_auto_save(&self) -> ELSResult<()> {
let params = ConfigurationParams {
items: vec![ConfigurationItem {
scope_uri: None,
section: Some("files.autoSave".to_string()),
}],
};
send(&json!({
"jsonrpc": "2.0",
"id": ASK_AUTO_SAVE_ID,
"method": "workspace/configuration",
"params": params,
}))
}
fn init_services(&mut self) { fn init_services(&mut self) {
let (senders, receivers) = SendChannels::new(); let (senders, receivers) = SendChannels::new();
self.channels = Some(senders); self.channels = Some(senders);
@ -745,8 +765,10 @@ impl<Checker: BuildRunnable, Parser: Parsable> Server<Checker, Parser> {
self.channels.as_ref().unwrap().health_check.send(())?; self.channels.as_ref().unwrap().health_check.send(())?;
} }
_ => { _ => {
_log!("received a unknown response: {msg}"); _log!("msg: {msg}");
// ignore at this time if msg.get("error").is_none() {
self.client_answers.borrow_mut().insert(id, msg.clone());
}
} }
} }
Ok(()) Ok(())