clangd_ext.rs

 1use std::sync::Arc;
 2
 3use ::serde::{Deserialize, Serialize};
 4use gpui::WeakEntity;
 5use language::CachedLspAdapter;
 6use lsp::LanguageServer;
 7use util::ResultExt as _;
 8
 9use crate::LspStore;
10
11pub const CLANGD_SERVER_NAME: &str = "clangd";
12
13#[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)]
14#[serde(rename_all = "camelCase")]
15pub struct InactiveRegionsParams {
16    pub text_document: lsp::OptionalVersionedTextDocumentIdentifier,
17    pub regions: Vec<lsp::Range>,
18}
19
20/// InactiveRegions is a clangd extension that marks regions of inactive code.
21pub struct InactiveRegions;
22
23impl lsp::notification::Notification for InactiveRegions {
24    type Params = InactiveRegionsParams;
25    const METHOD: &'static str = "textDocument/inactiveRegions";
26}
27
28pub fn register_notifications(
29    lsp_store: WeakEntity<LspStore>,
30    language_server: &LanguageServer,
31    adapter: Arc<CachedLspAdapter>,
32) {
33    if language_server.name().0 != CLANGD_SERVER_NAME {
34        return;
35    }
36    let server_id = language_server.server_id();
37
38    language_server
39        .on_notification::<InactiveRegions, _>({
40            let adapter = adapter.clone();
41            let this = lsp_store;
42
43            move |params: InactiveRegionsParams, mut cx| {
44                let adapter = adapter.clone();
45                this.update(&mut cx, |this, cx| {
46                    let diagnostics = params
47                        .regions
48                        .into_iter()
49                        .map(|range| lsp::Diagnostic {
50                            range,
51                            severity: Some(lsp::DiagnosticSeverity::INFORMATION),
52                            source: Some(CLANGD_SERVER_NAME.to_string()),
53                            message: "inactive region".to_string(),
54                            tags: Some(vec![lsp::DiagnosticTag::UNNECESSARY]),
55                            ..Default::default()
56                        })
57                        .collect();
58                    let mapped_diagnostics = lsp::PublishDiagnosticsParams {
59                        uri: params.text_document.uri,
60                        version: params.text_document.version,
61                        diagnostics,
62                    };
63                    this.update_diagnostics(
64                        server_id,
65                        mapped_diagnostics,
66                        &adapter.disk_based_diagnostic_sources,
67                        cx,
68                    )
69                    .log_err();
70                })
71                .ok();
72            }
73        })
74        .detach();
75}