use serde::{Deserialize, Serialize}; use serde_json::Value; use tower_lsp::jsonrpc::{Error, Result}; use tower_lsp::lsp_types::notification::Notification; use tower_lsp::lsp_types::*; use tower_lsp::{Client, LanguageServer, LspService, Server}; #[derive(Debug, Deserialize, Serialize)] struct CustomNotificationParams { title: String, message: String, } impl CustomNotificationParams { fn new(title: impl Into, message: impl Into) -> Self { CustomNotificationParams { title: title.into(), message: message.into(), } } } enum CustomNotification {} impl Notification for CustomNotification { type Params = CustomNotificationParams; const METHOD: &'static str = "custom/notification"; } #[derive(Debug)] struct Backend { client: Client, } #[tower_lsp::async_trait] impl LanguageServer for Backend { async fn initialize(&self, _: InitializeParams) -> Result { Ok(InitializeResult { server_info: None, capabilities: ServerCapabilities { execute_command_provider: Some(ExecuteCommandOptions { commands: vec!["custom.notification".to_string()], work_done_progress_options: Default::default(), }), ..ServerCapabilities::default() }, ..Default::default() }) } async fn shutdown(&self) -> Result<()> { Ok(()) } async fn execute_command(&self, params: ExecuteCommandParams) -> Result> { if params.command == "custom.notification" { self.client .send_notification::(CustomNotificationParams::new( "Hello", "Message", )) .await; self.client .log_message( MessageType::INFO, format!("Command executed with params: {params:?}"), ) .await; Ok(None) } else { Err(Error::invalid_request()) } } } #[tokio::main] async fn main() { #[cfg(feature = "runtime-agnostic")] use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt}; tracing_subscriber::fmt().init(); let (stdin, stdout) = (tokio::io::stdin(), tokio::io::stdout()); #[cfg(feature = "runtime-agnostic")] let (stdin, stdout) = (stdin.compat(), stdout.compat_write()); let (service, socket) = LspService::new(|client| Backend { client }); Server::new(stdin, stdout, socket).serve(service).await; }