Skip to main content

mdlint/server/
mod.rs

1mod capabilities;
2mod convert;
3mod documents;
4mod handlers;
5
6use crate::error::{MarkdownlintError, Result};
7use documents::DocumentStore;
8use lsp_server::{Connection, IoThreads, Message};
9
10/// Start an LSP server on stdio.
11pub fn run_server() -> Result<()> {
12    let (connection, io_threads) = Connection::stdio();
13    run_server_with_connection(connection, Some(io_threads))
14}
15
16/// Run the LSP event loop on an existing connection.
17///
18/// Exposed for integration testing via `Connection::memory()`.
19pub fn run_server_with_connection(
20    connection: Connection,
21    io_threads: Option<IoThreads>,
22) -> Result<()> {
23    let server_capabilities = serde_json::to_value(capabilities::capabilities())
24        .map_err(|e| MarkdownlintError::Lsp(e.to_string()))?;
25
26    connection
27        .initialize(server_capabilities)
28        .map_err(|e| MarkdownlintError::Lsp(e.to_string()))?;
29
30    let mut docs = DocumentStore::new();
31
32    for msg in &connection.receiver {
33        match msg {
34            Message::Request(req) => {
35                if connection
36                    .handle_shutdown(&req)
37                    .map_err(|e| MarkdownlintError::Lsp(e.to_string()))?
38                {
39                    if let Some(threads) = io_threads {
40                        threads
41                            .join()
42                            .map_err(|e| MarkdownlintError::Lsp(format!("{e}")))?;
43                    }
44                    return Ok(());
45                }
46                handlers::handle_request(&connection, &req, &mut docs);
47            }
48            Message::Notification(notif) => {
49                if notif.method == "exit" {
50                    if let Some(threads) = io_threads {
51                        threads
52                            .join()
53                            .map_err(|e| MarkdownlintError::Lsp(format!("{e}")))?;
54                    }
55                    return Ok(());
56                }
57                handlers::handle_notification(&connection, &notif, &mut docs);
58            }
59            Message::Response(_) => {}
60        }
61    }
62
63    Ok(())
64}