Expand description
A language server scaffold, exposing a synchronous crossbeam-channel based API. This crate handles protocol handshaking and parsing messages, while you control the message dispatch loop yourself.
Run with RUST_LOG=sync_lsp_server=debug
to see all the messages.
extern crate gen_lsp_server;
extern crate lsp_types;
extern crate failure;
extern crate crossbeam_channel;
use crossbeam_channel::{Sender, Receiver};
use lsp_types::{ServerCapabilities, InitializeParams, request::{GotoDefinition, GotoDefinitionResponse}};
use gen_lsp_server::{run_server, stdio_transport, handle_shutdown, RawMessage, RawResponse};
fn main() -> Result<(), failure::Error> {
let (receiver, sender, io_threads) = stdio_transport();
gen_lsp_server::run_server(
ServerCapabilities::default(),
receiver,
sender,
main_loop,
)?;
io_threads.join()?;
Ok(())
}
fn main_loop(
_params: InitializeParams,
receiver: &Receiver<RawMessage>,
sender: &Sender<RawMessage>,
) -> Result<(), failure::Error> {
for msg in receiver {
match msg {
RawMessage::Request(req) => {
let req = match handle_shutdown(req, sender) {
None => return Ok(()),
Some(req) => req,
};
let req = match req.cast::<GotoDefinition>() {
Ok((id, _params)) => {
let resp = RawResponse::ok::<GotoDefinition>(
id,
&Some(GotoDefinitionResponse::Array(Vec::new())),
);
sender.send(RawMessage::Response(resp));
continue;
},
Err(req) => req,
};
// ...
}
RawMessage::Response(_resp) => (),
RawMessage::Notification(_not) => (),
}
}
Ok(())
}
Structs§
Enums§
Functions§
- If
req
isShutdown
, respond to it and returnNone
, otherwise returnSome(req)
- Main entry point: runs the server from initialization to shutdown. To attach server to standard input/output streams, use the
stdio_transport
function to create correspondingsender
andreceiver
pair.