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    // TODO: inactiveRegions support needs do add diagnostics, not replace them as `this.update_diagnostics` call below does
39    if true {
40        return;
41    }
42    language_server
43        .on_notification::<InactiveRegions, _>({
44            let adapter = adapter.clone();
45            let this = lsp_store;
46
47            move |params: InactiveRegionsParams, cx| {
48                let adapter = adapter.clone();
49                this.update(cx, |this, cx| {
50                    let diagnostics = params
51                        .regions
52                        .into_iter()
53                        .map(|range| lsp::Diagnostic {
54                            range,
55                            severity: Some(lsp::DiagnosticSeverity::INFORMATION),
56                            source: Some(CLANGD_SERVER_NAME.to_string()),
57                            message: "inactive region".to_string(),
58                            tags: Some(vec![lsp::DiagnosticTag::UNNECESSARY]),
59                            ..Default::default()
60                        })
61                        .collect();
62                    let mapped_diagnostics = lsp::PublishDiagnosticsParams {
63                        uri: params.text_document.uri,
64                        version: params.text_document.version,
65                        diagnostics,
66                    };
67                    this.update_diagnostics(
68                        server_id,
69                        mapped_diagnostics,
70                        &adapter.disk_based_diagnostic_sources,
71                        cx,
72                    )
73                    .log_err();
74                })
75                .ok();
76            }
77        })
78        .detach();
79}