backtrace_ls/lsp/
server.rs1use std::sync::Arc;
4
5use async_lsp::{
6 client_monitor::ClientProcessMonitorLayer,
7 concurrency::ConcurrencyLayer,
8 lsp_types::{
9 CodeActionKind, CodeActionOptions, CodeActionProviderCapability, DiagnosticOptions,
10 DiagnosticServerCapabilities, ExecuteCommandOptions, ServerCapabilities, ServerInfo,
11 TextDocumentSyncCapability, TextDocumentSyncKind, WorkDoneProgressOptions,
12 },
13 panic::CatchUnwindLayer,
14 router::Router,
15 server::LifecycleLayer,
16};
17use tokio::io::{stdin, stdout};
18use tokio_util::compat::{TokioAsyncReadCompatExt, TokioAsyncWriteCompatExt};
19use tower::ServiceBuilder;
20
21use super::{code_action, handlers, state::ServerState};
22use crate::{Config, error::LSError};
23
24#[must_use]
25pub fn server_capabilities() -> ServerCapabilities {
26 ServerCapabilities {
27 diagnostic_provider: Some(DiagnosticServerCapabilities::Options(DiagnosticOptions {
28 identifier: None,
29 inter_file_dependencies: false,
30 workspace_diagnostics: true,
31 work_done_progress_options: WorkDoneProgressOptions::default(),
32 })),
33 text_document_sync: Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::NONE)),
34 code_action_provider: Some(CodeActionProviderCapability::Options(CodeActionOptions {
35 code_action_kinds: Some(vec![CodeActionKind::QUICKFIX]),
36 work_done_progress_options: WorkDoneProgressOptions::default(),
37 resolve_provider: None,
38 })),
39 execute_command_provider: Some(ExecuteCommandOptions {
40 commands: code_action::all_commands(),
41 work_done_progress_options: WorkDoneProgressOptions::default(),
42 }),
43 ..ServerCapabilities::default()
44 }
45}
46
47#[must_use]
48pub fn server_info() -> ServerInfo {
49 ServerInfo {
50 name: "backtrace-ls".to_string(),
51 version: Some(env!("CARGO_PKG_VERSION").to_string()),
52 }
53}
54
55pub async fn run(config: Config) -> Result<(), LSError> {
57 let (server, _) = async_lsp::MainLoop::new_server(|client| {
58 let state = ServerState::new(client.clone(), config.clone());
59 let mut router = Router::new(Arc::clone(&state));
60
61 handlers::register_all(&mut router, &state);
62
63 ServiceBuilder::new()
64 .layer(LifecycleLayer::default())
65 .layer(CatchUnwindLayer::default())
66 .layer(ConcurrencyLayer::default())
67 .layer(ClientProcessMonitorLayer::new(client))
68 .service(router)
69 });
70
71 let (stdin, stdout) = (stdin().compat(), stdout().compat_write());
72
73 server
74 .run_buffered(stdin, stdout)
75 .await
76 .map_err(|e| LSError::Generic(format!("LSP server error: {e}")))?;
77
78 Ok(())
79}