Add Copilot server to LSP logs panel

Kirill Bulatov created

Change summary

crates/copilot/src/copilot.rs |  8 ++++++++
crates/project/src/project.rs | 20 ++++++++++++++++++++
2 files changed, 28 insertions(+)

Detailed changes

crates/copilot/src/copilot.rs 🔗

@@ -572,6 +572,14 @@ impl Copilot {
         cx.foreground().spawn(start_task)
     }
 
+    pub fn language_server(&self) -> Option<&Arc<LanguageServer>> {
+        if let CopilotServer::Running(server) = &self.server {
+            Some(&server.lsp)
+        } else {
+            None
+        }
+    }
+
     pub fn register_buffer(&mut self, buffer: &ModelHandle<Buffer>, cx: &mut ModelContext<Self>) {
         let weak_buffer = buffer.downgrade();
         self.buffers.insert(weak_buffer.clone());

crates/project/src/project.rs 🔗

@@ -108,6 +108,7 @@ pub struct Project {
     active_entry: Option<ProjectEntryId>,
     buffer_ordered_messages_tx: mpsc::UnboundedSender<BufferOrderedMessage>,
     languages: Arc<LanguageRegistry>,
+    supplementary_language_servers: HashMap<LanguageServerId, Arc<LanguageServer>>,
     language_servers: HashMap<LanguageServerId, LanguageServerState>,
     language_server_ids: HashMap<(WorktreeId, LanguageServerName), LanguageServerId>,
     language_server_statuses: BTreeMap<LanguageServerId, LanguageServerStatus>,
@@ -647,6 +648,7 @@ impl Project {
                 fs,
                 next_entry_id: Default::default(),
                 next_diagnostic_group_id: Default::default(),
+                supplementary_language_servers: HashMap::default(),
                 language_servers: Default::default(),
                 language_server_ids: Default::default(),
                 language_server_statuses: Default::default(),
@@ -723,6 +725,7 @@ impl Project {
                     remote_id,
                     replica_id,
                 }),
+                supplementary_language_servers: HashMap::default(),
                 language_servers: Default::default(),
                 language_server_ids: Default::default(),
                 language_server_statuses: response
@@ -1915,6 +1918,7 @@ impl Project {
         self.detect_language_for_buffer(buffer, cx);
         self.register_buffer_with_language_servers(buffer, cx);
         self.register_buffer_with_copilot(buffer, cx);
+        self.register_copilot_language_server(cx);
         cx.observe_release(buffer, |this, buffer, cx| {
             if let Some(file) = File::from_dyn(buffer.file()) {
                 if file.is_local() {
@@ -2067,6 +2071,20 @@ impl Project {
         }
     }
 
+    fn register_copilot_language_server(&mut self, cx: &mut ModelContext<Self>) {
+        if let Some(copilot_language_server) =
+            Copilot::global(cx).and_then(|copilot| copilot.read(cx).language_server())
+        {
+            let new_server_id = copilot_language_server.server_id();
+            if let hash_map::Entry::Vacant(v) =
+                self.supplementary_language_servers.entry(new_server_id)
+            {
+                v.insert(Arc::clone(copilot_language_server));
+                cx.emit(Event::LanguageServerAdded(new_server_id))
+            }
+        }
+    }
+
     async fn send_buffer_ordered_messages(
         this: WeakModelHandle<Self>,
         rx: UnboundedReceiver<BufferOrderedMessage>,
@@ -7945,6 +7963,8 @@ impl Project {
     pub fn language_server_for_id(&self, id: LanguageServerId) -> Option<Arc<LanguageServer>> {
         if let LanguageServerState::Running { server, .. } = self.language_servers.get(&id)? {
             Some(server.clone())
+        } else if let Some(server) = self.supplementary_language_servers.get(&id) {
+            Some(Arc::clone(server))
         } else {
             None
         }