pub struct LspServer {
pub notification_rx: Receiver<LspNotification>,
/* private fields */
}Expand description
Managed LSP server instance with capabilities and encoding.
Fields§
§notification_rx: Receiver<LspNotification>Receiver for push notifications from the LSP server.
Extract this before registering the server to receive real-time
notifications (e.g., textDocument/publishDiagnostics, $/progress).
Implementations§
Source§impl LspServer
impl LspServer
Sourcepub fn take_notification_rx(&mut self) -> Receiver<LspNotification>
pub fn take_notification_rx(&mut self) -> Receiver<LspNotification>
Take the notification receiver out of this server, replacing it with a dummy channel.
Use this to extract the receiver for a background pump task before registering
the server with the translator. After this call, the server’s notification_rx
will never receive messages.
Sourcepub async fn spawn(config: ServerInitConfig) -> Result<Self>
pub async fn spawn(config: ServerInitConfig) -> Result<Self>
Spawn and initialize LSP server.
This performs the complete initialization sequence:
- Spawns the LSP server as a child process
- Sends initialize request with client capabilities
- Receives server capabilities from initialize response
- Sends initialized notification
§Errors
Returns an error if:
- Server process fails to spawn
- Initialize request fails or times out
- Server returns error during initialization
Sourcepub const fn capabilities(&self) -> &ServerCapabilities
pub const fn capabilities(&self) -> &ServerCapabilities
Get server capabilities.
Sourcepub fn position_encoding(&self) -> PositionEncodingKind
pub fn position_encoding(&self) -> PositionEncodingKind
Get negotiated position encoding.
Sourcepub fn has_exited(&mut self) -> Result<bool>
pub fn has_exited(&mut self) -> Result<bool>
Non-blocking check for whether the child process has already exited.
Uses tokio::process::Child::try_wait, which never blocks waiting
for the process: true means it is gone (crashed, killed, or exited
on its own), and any LspClient obtained from Self::client is
now permanently disconnected – new requests through it fail with
crate::error::Error::ServerTerminated. Callers that want to
recover substitute a freshly Self::spawned replacement.
§Errors
Returns an error if the OS fails to report the process’s status.
Sourcepub async fn shutdown(self) -> Result<()>
pub async fn shutdown(self) -> Result<()>
Shutdown server gracefully.
Sends the LSP shutdown request, waits for the response, sends the
exit notification, then waits up to a fixed grace period for the
child process to exit on its own. If it hasn’t by then, or if the
shutdown/exit handshake itself fails, the child is simply dropped
here — kill_on_drop terminates it via SIGKILL (a no-op if it has
already exited).
§Errors
Returns an error if the shutdown/exit handshake fails. The child
process is still torn down (gracefully if it exits in time, killed
otherwise) regardless of whether this returns Ok or Err.
Sourcepub async fn spawn_batch(configs: &[ServerInitConfig]) -> ServerInitResult
pub async fn spawn_batch(configs: &[ServerInitConfig]) -> ServerInitResult
Spawn multiple LSP servers in batch mode with graceful degradation.
Attempts to spawn and initialize all configured servers. If some servers fail to spawn, the successful servers are still returned. This enables graceful degradation where the system can continue to operate with partial functionality.
§Behavior
- Attempts to spawn each server sequentially
- Logs success (info) and failure (error) for each server
- Accumulates successful servers and failures
- Never panics or returns early - attempts all servers
§Examples
use mcpls_core::lsp::{LspServer, ServerInitConfig};
use mcpls_core::config::LspServerConfig;
use std::path::PathBuf;
let configs = vec![
ServerInitConfig {
server_config: LspServerConfig::rust_analyzer(),
workspace_roots: vec![PathBuf::from("/workspace")],
initialization_options: None,
position_encodings: vec!["utf-8".to_string(), "utf-16".to_string()],
notification_tx: None,
},
ServerInitConfig {
server_config: LspServerConfig::pyright(),
workspace_roots: vec![PathBuf::from("/workspace")],
initialization_options: None,
position_encodings: vec!["utf-8".to_string(), "utf-16".to_string()],
notification_tx: None,
},
];
let result = LspServer::spawn_batch(&configs).await;
if result.has_servers() {
println!("Successfully spawned {} servers", result.server_count());
}
if result.partial_success() {
eprintln!("Warning: {} servers failed", result.failure_count());
}