Skip to content

Commit fc7a459

Browse files
committed
Add richer LSP server example (#20017)
1 parent 0ac6559 commit fc7a459

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

crates/rust-analyzer/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,3 +106,7 @@ in-rust-tree = [
106106

107107
[lints]
108108
workspace = true
109+
110+
[[example]]
111+
name = "rust_analyzer_lsp_example"
112+
path = "examples/rust_analyzer_lsp_example/main.rs"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//! rust-analyzer LSP example
2+
//!
3+
//! A minimal Language Server Protocol server demonstrating how to embed
4+
//! `rust-analyzer` as a library. To run it:
5+
//! ```bash
6+
//! cargo run --example rust_analyzer_lsp_example
7+
//
8+
use anyhow::Result;
9+
use lsp_server::{Connection, Message};
10+
use lsp_types::{
11+
CompletionParams, DidChangeTextDocumentParams, DocumentFormattingParams, OneOf,
12+
ServerCapabilities, TextDocumentSyncKind, TextDocumentSyncOptions,
13+
request::{Completion, Formatting, Request as LspRequest},
14+
};
15+
use serde_json::json;
16+
17+
fn main() -> Result<()> {
18+
// Set up a JSON-RPC connection over stdio
19+
let (connection, io_threads) = Connection::stdio();
20+
21+
// Perform the initialize handshake and advertise capabilities
22+
let (init_id, _init_params) = connection.initialize_start()?;
23+
let capabilities = ServerCapabilities {
24+
text_document_sync: Some(
25+
TextDocumentSyncOptions {
26+
change: Some(TextDocumentSyncKind::FULL),
27+
..Default::default()
28+
}
29+
.into(),
30+
),
31+
completion_provider: Some(Default::default()),
32+
document_formatting_provider: Some(OneOf::Left(true)),
33+
..Default::default()
34+
};
35+
connection.initialize_finish(init_id, json!({ "capabilities": capabilities }))?;
36+
37+
// Enter the main message loop
38+
for message in connection.receiver.iter() {
39+
match message {
40+
Message::Notification(notification)
41+
if notification.method == "textDocument/didChange" =>
42+
{
43+
let params: DidChangeTextDocumentParams =
44+
serde_json::from_value(notification.params).unwrap();
45+
eprintln!("Document changed: {}", params.text_document.uri);
46+
}
47+
Message::Request(request) if request.method == Completion::METHOD => {
48+
let _: CompletionParams = serde_json::from_value(request.params).unwrap();
49+
let response = lsp_server::Response::new_ok(
50+
request.id,
51+
json!({ "isIncomplete": false, "items": [] }),
52+
);
53+
connection.sender.send(Message::Response(response)).unwrap();
54+
}
55+
Message::Request(request) if request.method == Formatting::METHOD => {
56+
let _: DocumentFormattingParams = serde_json::from_value(request.params).unwrap();
57+
let response = lsp_server::Response::new_ok(request.id, json!([]));
58+
connection.sender.send(Message::Response(response)).unwrap();
59+
}
60+
Message::Request(request) if connection.handle_shutdown(&request)? => break,
61+
_ => {} // ignore all other messages
62+
}
63+
}
64+
65+
io_threads.join().unwrap();
66+
Ok(())
67+
}

0 commit comments

Comments
 (0)