diff --git a/crates/copilot/src/copilot.rs b/crates/copilot/src/copilot.rs index 0361c9b46c069470f95d862b7d3361cbacd2a634..18ffb0886758b4f8074fa56568aea71296c8f1af 100644 --- a/crates/copilot/src/copilot.rs +++ b/crates/copilot/src/copilot.rs @@ -276,8 +276,12 @@ pub struct Copilot { server_id: LanguageServerId, } +pub enum Event { + CopilotReady, +} + impl Entity for Copilot { - type Event = (); + type Event = Event; fn app_will_quit( &mut self, @@ -881,6 +885,7 @@ impl Copilot { self.register_buffer(&buffer, cx); } } + cx.emit(Event::CopilotReady); } request::SignInStatus::NotAuthorized { .. } => { server.sign_in_status = SignInStatus::Unauthorized; diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index 2aa73fa52c253030f5bcb8e3ba94052cf367f7df..c1c5e41dbac35de6e5534322db3b19a2d98e1723 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -148,7 +148,7 @@ pub struct Project { _maintain_buffer_languages: Task<()>, _maintain_workspace_config: Task<()>, terminals: Terminals, - copilot_enabled: bool, + copilot_lsp_subscription: Option, current_lsp_settings: HashMap, LspSettings>, } @@ -619,6 +619,8 @@ impl Project { let (tx, rx) = mpsc::unbounded(); cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx)) .detach(); + let copilot_lsp_subscription = + Copilot::global(cx).map(|copilot| subscribe_for_copilot_events(&copilot, cx)); Self { worktrees: Default::default(), buffer_ordered_messages_tx: tx, @@ -660,7 +662,7 @@ impl Project { terminals: Terminals { local_handles: Vec::new(), }, - copilot_enabled: Copilot::global(cx).is_some(), + copilot_lsp_subscription, current_lsp_settings: settings::get::(cx).lsp.clone(), } }) @@ -696,6 +698,8 @@ impl Project { let (tx, rx) = mpsc::unbounded(); cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx)) .detach(); + let copilot_lsp_subscription = + Copilot::global(cx).map(|copilot| subscribe_for_copilot_events(&copilot, cx)); let mut this = Self { worktrees: Vec::new(), buffer_ordered_messages_tx: tx, @@ -754,7 +758,7 @@ impl Project { terminals: Terminals { local_handles: Vec::new(), }, - copilot_enabled: Copilot::global(cx).is_some(), + copilot_lsp_subscription, current_lsp_settings: settings::get::(cx).lsp.clone(), }; for worktree in worktrees { @@ -885,12 +889,14 @@ impl Project { self.restart_language_servers(worktree, language, cx); } - if !self.copilot_enabled && Copilot::global(cx).is_some() { - self.copilot_enabled = true; - for buffer in self.opened_buffers.values() { - if let Some(buffer) = buffer.upgrade(cx) { - self.register_buffer_with_copilot(&buffer, cx); + if self.copilot_lsp_subscription.is_none() { + if let Some(copilot) = Copilot::global(cx) { + for buffer in self.opened_buffers.values() { + if let Some(buffer) = buffer.upgrade(cx) { + self.register_buffer_with_copilot(&buffer, cx); + } } + self.copilot_lsp_subscription = Some(subscribe_for_copilot_events(&copilot, cx)); } } @@ -1918,7 +1924,6 @@ 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() { @@ -2071,20 +2076,6 @@ impl Project { } } - fn register_copilot_language_server(&mut self, cx: &mut ModelContext) { - 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, rx: UnboundedReceiver, @@ -8024,6 +8015,28 @@ impl Project { } } +fn subscribe_for_copilot_events( + copilot: &ModelHandle, + cx: &mut ModelContext<'_, Project>, +) -> gpui::Subscription { + cx.subscribe( + copilot, + |project, copilot, copilot_event, cx| match copilot_event { + copilot::Event::CopilotReady => { + if let Some(copilot_server) = copilot.read(cx).language_server() { + let new_server_id = copilot_server.server_id(); + if let hash_map::Entry::Vacant(v) = + project.supplementary_language_servers.entry(new_server_id) + { + v.insert(Arc::clone(copilot_server)); + cx.emit(Event::LanguageServerAdded(new_server_id)) + } + } + } + }, + ) +} + fn glob_literal_prefix<'a>(glob: &'a str) -> &'a str { let mut literal_end = 0; for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {