matrixcode_core/lsp/
registry.rs1use anyhow::Result;
6use std::collections::HashMap;
7use std::path::Path;
8use std::sync::Arc;
9use tokio::sync::RwLock;
10
11use super::client::LspClient;
12use super::types::LspServerConfig;
13
14pub struct LspClientRegistry {
16 clients: Arc<RwLock<HashMap<String, Arc<LspClient>>>>,
18}
19
20impl LspClientRegistry {
21 pub fn new() -> Self {
23 Self {
24 clients: Arc::new(RwLock::new(HashMap::new())),
25 }
26 }
27
28 pub async fn register(&self, config: &LspServerConfig, project_root: &Path) -> Result<()> {
30 let client = LspClient::from_config(config, project_root.to_path_buf());
31 client.spawn(config).await?;
32 let mut clients = self.clients.write().await;
33 clients.insert(config.language.clone(), Arc::new(client));
34 log::info!("LSP client registered for language: {}", config.language);
35 Ok(())
36 }
37
38 pub async fn get_client(&self, language: &str) -> Option<Arc<LspClient>> {
40 let clients = self.clients.read().await;
41 clients.get(language).cloned()
42 }
43
44 pub async fn has_active_clients(&self) -> bool {
46 let clients = self.clients.read().await;
47 !clients.is_empty()
48 }
49
50 pub async fn active_languages(&self) -> Vec<String> {
52 let clients = self.clients.read().await;
53 clients.keys().cloned().collect()
54 }
55
56 pub async fn shutdown_all(&self) -> Result<()> {
58 let mut clients = self.clients.write().await;
59 for (language, client) in clients.iter() {
60 if let Err(e) = client.shutdown().await {
61 log::warn!("Failed to shutdown LSP client '{}': {}", language, e);
62 }
63 }
64 clients.clear();
65 Ok(())
66 }
67}
68
69impl Default for LspClientRegistry {
70 fn default() -> Self {
71 Self::new()
72 }
73}