|
| 1 | +mod cmd_args; |
| 2 | +mod context; |
| 3 | +mod handlers; |
| 4 | +mod logger; |
| 5 | +mod meta_text; |
| 6 | +mod util; |
| 7 | + |
| 8 | +pub use clap::Parser; |
| 9 | +pub use cmd_args::*; |
| 10 | +use handlers::{ |
| 11 | + initialized_handler, on_notification_handler, on_req_handler, on_response_handler, |
| 12 | + server_capabilities, |
| 13 | +}; |
| 14 | +use lsp_server::{Connection, Message}; |
| 15 | +use lsp_types::InitializeParams; |
| 16 | +use std::{env, error::Error}; |
| 17 | + |
| 18 | +#[macro_use] |
| 19 | +extern crate rust_i18n; |
| 20 | +rust_i18n::i18n!("./locales", fallback = "en"); |
| 21 | + |
| 22 | +const CRATE_NAME: &str = env!("CARGO_PKG_NAME"); |
| 23 | +const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); |
| 24 | + |
| 25 | +#[allow(unused)] |
| 26 | +async fn run_ls(cmd_args: CmdArgs) -> Result<(), Box<dyn Error + Sync + Send>> { |
| 27 | + let (connection, threads) = match cmd_args.communication { |
| 28 | + cmd_args::Communication::Stdio => Connection::stdio(), |
| 29 | + cmd_args::Communication::Tcp => { |
| 30 | + let port = cmd_args.port; |
| 31 | + let ip = cmd_args.ip.clone(); |
| 32 | + let addr = (ip.as_str(), port); |
| 33 | + Connection::listen(addr).unwrap() |
| 34 | + } |
| 35 | + }; |
| 36 | + |
| 37 | + let (id, params) = connection.initialize_start()?; |
| 38 | + let initialization_params: InitializeParams = serde_json::from_value(params).unwrap(); |
| 39 | + let server_capbilities = server_capabilities(&initialization_params.capabilities); |
| 40 | + let initialize_data = serde_json::json!({ |
| 41 | + "capabilities": server_capbilities, |
| 42 | + "serverInfo": { |
| 43 | + "name": CRATE_NAME, |
| 44 | + "version": CRATE_VERSION |
| 45 | + } |
| 46 | + }); |
| 47 | + |
| 48 | + connection.initialize_finish(id, initialize_data)?; |
| 49 | + |
| 50 | + main_loop(connection, initialization_params, cmd_args).await?; |
| 51 | + threads.join()?; |
| 52 | + |
| 53 | + eprintln!("Server shutting down."); |
| 54 | + Ok(()) |
| 55 | +} |
| 56 | + |
| 57 | +async fn main_loop( |
| 58 | + connection: Connection, |
| 59 | + params: InitializeParams, |
| 60 | + cmd_args: CmdArgs, |
| 61 | +) -> Result<(), Box<dyn Error + Sync + Send>> { |
| 62 | + let mut server_context = context::ServerContext::new(Connection { |
| 63 | + sender: connection.sender.clone(), |
| 64 | + receiver: connection.receiver.clone(), |
| 65 | + }); |
| 66 | + |
| 67 | + let server_context_snapshot = server_context.snapshot(); |
| 68 | + tokio::spawn(async move { |
| 69 | + initialized_handler(server_context_snapshot, params, cmd_args).await; |
| 70 | + }); |
| 71 | + |
| 72 | + for msg in &connection.receiver { |
| 73 | + match msg { |
| 74 | + Message::Request(req) => { |
| 75 | + if connection.handle_shutdown(&req)? { |
| 76 | + server_context.close().await; |
| 77 | + return Ok(()); |
| 78 | + } |
| 79 | + |
| 80 | + on_req_handler(req, &mut server_context).await?; |
| 81 | + } |
| 82 | + Message::Notification(notify) => { |
| 83 | + on_notification_handler(notify, &mut server_context).await?; |
| 84 | + } |
| 85 | + Message::Response(response) => { |
| 86 | + on_response_handler(response, &mut server_context).await?; |
| 87 | + } |
| 88 | + } |
| 89 | + } |
| 90 | + |
| 91 | + server_context.close().await; |
| 92 | + Ok(()) |
| 93 | +} |
0 commit comments