diff --git a/crates/els/diagnostics.rs b/crates/els/diagnostics.rs index 24c84d61..ef3e090d 100644 --- a/crates/els/diagnostics.rs +++ b/crates/els/diagnostics.rs @@ -19,9 +19,11 @@ use lsp_types::{ }; use serde_json::json; +use crate::_log; use crate::diff::{ASTDiff, HIRDiff}; 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}; @@ -204,7 +206,8 @@ impl Server { } let params = PublishDiagnosticsParams::new(uri, diagnostics, None); if self - .client_capas + .init_params + .capabilities .text_document .as_ref() .map(|doc| doc.publish_diagnostics.is_some()) @@ -229,6 +232,25 @@ impl Server { move || { let mut file_vers = Dict::::new(); 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() { let Some(latest_ver) = _self.file_cache.get_ver(&uri) else { continue; diff --git a/crates/els/server.rs b/crates/els/server.rs index d534a66e..43e76047 100644 --- a/crates/els/server.rs +++ b/crates/els/server.rs @@ -32,12 +32,13 @@ use lsp_types::request::{ WillRenameFiles, }; use lsp_types::{ - ClientCapabilities, CodeActionKind, CodeActionOptions, CodeActionProviderCapability, - CodeLensOptions, CompletionOptions, DidChangeTextDocumentParams, DidOpenTextDocumentParams, - ExecuteCommandOptions, HoverProviderCapability, InitializeResult, InlayHintOptions, - InlayHintServerCapabilities, OneOf, Position, SemanticTokenType, SemanticTokensFullOptions, - SemanticTokensLegend, SemanticTokensOptions, SemanticTokensServerCapabilities, - ServerCapabilities, SignatureHelpOptions, WorkDoneProgressOptions, + CodeActionKind, CodeActionOptions, CodeActionProviderCapability, CodeLensOptions, + CompletionOptions, ConfigurationItem, ConfigurationParams, DidChangeTextDocumentParams, + DidOpenTextDocumentParams, ExecuteCommandOptions, HoverProviderCapability, InitializeParams, + InitializeResult, InlayHintOptions, InlayHintServerCapabilities, OneOf, Position, + SemanticTokenType, SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions, + SemanticTokensServerCapabilities, ServerCapabilities, SignatureHelpOptions, + WorkDoneProgressOptions, }; use serde::{Deserialize, Serialize}; @@ -52,6 +53,7 @@ use crate::message::{ErrorMessage, LSPResult, LogMessage, ShowMessage}; use crate::util::{self, NormalizedUrl}; pub const HEALTH_CHECKER_ID: i64 = 10000; +pub const ASK_AUTO_SAVE_ID: i64 = 10001; pub type ELSResult = Result>; @@ -312,7 +314,8 @@ pub struct Server>, pub(crate) disabled_features: Vec, pub(crate) opt_features: Vec, pub(crate) file_cache: FileCache, @@ -332,7 +335,8 @@ impl Clone for Server { cfg: self.cfg.clone(), home: self.home.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(), opt_features: self.opt_features.clone(), file_cache: self.file_cache.clone(), @@ -354,7 +358,8 @@ impl Server { cfg, home: normalize_path(std::env::current_dir().unwrap_or_default()), erg_path: erg_path().clone(), // already normalized - client_capas: ClientCapabilities::default(), + init_params: InitializeParams::default(), + client_answers: Shared::new(Dict::new()), disabled_features: vec![], opt_features: vec![], file_cache: FileCache::new(), @@ -390,7 +395,7 @@ impl Server { send_log("initializing ELS")?; // #[allow(clippy::collapsible_if)] 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))?; } let mut args = self.cfg.runtime_args.iter(); @@ -503,6 +508,21 @@ impl Server { 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) { let (senders, receivers) = SendChannels::new(); self.channels = Some(senders); @@ -745,8 +765,10 @@ impl Server { self.channels.as_ref().unwrap().health_check.send(())?; } _ => { - _log!("received a unknown response: {msg}"); - // ignore at this time + _log!("msg: {msg}"); + if msg.get("error").is_none() { + self.client_answers.borrow_mut().insert(id, msg.clone()); + } } } Ok(())