diff --git a/jsonrpc/src/lib.rs b/jsonrpc/src/lib.rs index 12d94adf7..93a939295 100644 --- a/jsonrpc/src/lib.rs +++ b/jsonrpc/src/lib.rs @@ -6,7 +6,7 @@ mod types; pub use self::{ client::{Client, ResponseHandler}, - server::{handle_notification, handle_request, Server}, + server::{handle_notification, handle_request, Server, EventHandler}, types::*, }; @@ -26,7 +26,7 @@ pub struct MessageHandler { impl MessageHandler where - S: Server + Send + Sync + 'static, + S: Server + EventHandler + Send + Sync + 'static, H: ResponseHandler + Send + Sync + 'static, I: Stream> + Unpin, O: Sink + Unpin + Send + 'static, @@ -64,12 +64,18 @@ where let json = serde_json::to_string(&response).unwrap(); let mut output = await!(output.lock()); await!(output.send(json)); + await!(server.handle_events()); }; self.pool.spawn(handler).unwrap(); } Ok(Message::Notification(notification)) => { self.server.handle_notification(notification); + + let server = Arc::clone(&self.server); + self.pool.spawn(async move { + await!(server.handle_events()); + }); } Ok(Message::Response(response)) => { await!(self.response_handler.handle(response)); diff --git a/jsonrpc/src/server.rs b/jsonrpc/src/server.rs index db09c1a34..b4b61c4c0 100644 --- a/jsonrpc/src/server.rs +++ b/jsonrpc/src/server.rs @@ -13,6 +13,10 @@ pub trait Server { fn handle_notification(&self, notification: Notification); } +pub trait EventHandler { + fn handle_events(&self) -> BoxFuture<'_, ()>; +} + const DESERIALIZE_OBJECT_ERROR: &str = "Could not deserialize parameter object"; pub async fn handle_request<'a, H, F, I, O>(request: Request, handler: H) -> Response diff --git a/src/event.rs b/src/event.rs new file mode 100644 index 000000000..872ea1dae --- /dev/null +++ b/src/event.rs @@ -0,0 +1,23 @@ +use std::sync::Mutex; + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum Event { + WorkspaceChanged, +} + +#[derive(Debug, Default)] +pub struct EventManager { + events: Mutex>, +} + +impl EventManager { + pub fn push(&self, event: Event) { + let mut events = self.events.lock().unwrap(); + events.push(event); + } + + pub fn take(&self) -> Vec { + let mut events = self.events.lock().unwrap(); + std::mem::replace(&mut *events, Vec::new()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 309fa3703..cf85b4e45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ pub mod codec; pub mod completion; pub mod data; pub mod definition; +pub mod event; pub mod feature; pub mod folding; pub mod formatting; diff --git a/src/server.rs b/src/server.rs index f86bf40f2..07e72957b 100644 --- a/src/server.rs +++ b/src/server.rs @@ -24,10 +24,14 @@ use serde::de::DeserializeOwned; use std::borrow::Cow; use std::sync::Arc; use walkdir::WalkDir; +use futures::future::BoxFuture; +use futures::prelude::*; +use crate::event::{Event, EventManager}; pub struct LatexLspServer { client: Arc, workspace_manager: WorkspaceManager, + event_manager: EventManager, } #[jsonrpc_server] @@ -36,6 +40,7 @@ impl LatexLspServer { LatexLspServer { client, workspace_manager: WorkspaceManager::new(), + event_manager: EventManager::default(), } } @@ -51,12 +56,6 @@ impl LatexLspServer { } } - let workspace = self.workspace_manager.get(); - workspace - .documents - .iter() - .for_each(|x| info!("{}", x.uri.as_str())); - let capabilities = ServerCapabilities { text_document_sync: Some(TextDocumentSyncCapability::Options( TextDocumentSyncOptions { @@ -99,15 +98,17 @@ impl LatexLspServer { } #[jsonrpc_method("initialized", kind = "notification")] - pub fn initialized(&self, params: InitializedParams) {} + pub fn initialized(&self, _params: InitializedParams) { + self.event_manager.push(Event::WorkspaceChanged); + } #[jsonrpc_method("shutdown", kind = "request")] - pub async fn shutdown(&self, params: ()) -> Result<()> { + pub async fn shutdown(&self, _params: ()) -> Result<()> { Ok(()) } #[jsonrpc_method("exit", kind = "notification")] - pub fn exit(&self, params: ()) {} + pub fn exit(&self, _params: ()) {} #[jsonrpc_method("workspace/didChangeWatchedFiles", kind = "notification")] pub fn did_change_watched_files(&self, params: DidChangeWatchedFilesParams) {} @@ -115,6 +116,7 @@ impl LatexLspServer { #[jsonrpc_method("textDocument/didOpen", kind = "notification")] pub fn did_open(&self, params: DidOpenTextDocumentParams) { self.workspace_manager.add(params.text_document); + self.event_manager.push(Event::WorkspaceChanged); } #[jsonrpc_method("textDocument/didChange", kind = "notification")] @@ -123,13 +125,16 @@ impl LatexLspServer { let uri = params.text_document.uri.clone(); self.workspace_manager.update(uri, change.text); } + self.event_manager.push(Event::WorkspaceChanged); } #[jsonrpc_method("textDocument/didSave", kind = "notification")] - pub fn did_save(&self, params: DidSaveTextDocumentParams) {} + pub fn did_save(&self, _params: DidSaveTextDocumentParams) { + self.event_manager.push(Event::WorkspaceChanged); + } #[jsonrpc_method("textDocument/didClose", kind = "notification")] - pub fn did_close(&self, params: DidCloseTextDocumentParams) {} + pub fn did_close(&self, _params: DidCloseTextDocumentParams) {} #[jsonrpc_method("textDocument/completion", kind = "request")] pub async fn completion(&self, params: CompletionParams) -> Result { @@ -266,6 +271,21 @@ impl LatexLspServer { } } +impl jsonrpc::EventHandler for LatexLspServer { + fn handle_events(&self) -> BoxFuture<'_, ()> { + let handler = async move { + for event in self.event_manager.take() { + match event { + Event::WorkspaceChanged => { + log::info!("TODO: Workspace Changed"); + } + } + } + }; + handler.boxed() + } +} + #[macro_export] macro_rules! request { ($server:expr, $params:expr) => {{