Send and receive Copilot events

This commit is contained in:
Kirill Bulatov 2023-09-19 21:53:31 +03:00
parent 9eadfc80ba
commit 556f398780
2 changed files with 42 additions and 24 deletions

View file

@ -276,8 +276,12 @@ pub struct Copilot {
server_id: LanguageServerId, server_id: LanguageServerId,
} }
pub enum Event {
CopilotReady,
}
impl Entity for Copilot { impl Entity for Copilot {
type Event = (); type Event = Event;
fn app_will_quit( fn app_will_quit(
&mut self, &mut self,
@ -881,6 +885,7 @@ impl Copilot {
self.register_buffer(&buffer, cx); self.register_buffer(&buffer, cx);
} }
} }
cx.emit(Event::CopilotReady);
} }
request::SignInStatus::NotAuthorized { .. } => { request::SignInStatus::NotAuthorized { .. } => {
server.sign_in_status = SignInStatus::Unauthorized; server.sign_in_status = SignInStatus::Unauthorized;

View file

@ -148,7 +148,7 @@ pub struct Project {
_maintain_buffer_languages: Task<()>, _maintain_buffer_languages: Task<()>,
_maintain_workspace_config: Task<()>, _maintain_workspace_config: Task<()>,
terminals: Terminals, terminals: Terminals,
copilot_enabled: bool, copilot_lsp_subscription: Option<gpui::Subscription>,
current_lsp_settings: HashMap<Arc<str>, LspSettings>, current_lsp_settings: HashMap<Arc<str>, LspSettings>,
} }
@ -619,6 +619,8 @@ impl Project {
let (tx, rx) = mpsc::unbounded(); let (tx, rx) = mpsc::unbounded();
cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx)) cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx))
.detach(); .detach();
let copilot_lsp_subscription =
Copilot::global(cx).map(|copilot| subscribe_for_copilot_events(&copilot, cx));
Self { Self {
worktrees: Default::default(), worktrees: Default::default(),
buffer_ordered_messages_tx: tx, buffer_ordered_messages_tx: tx,
@ -660,7 +662,7 @@ impl Project {
terminals: Terminals { terminals: Terminals {
local_handles: Vec::new(), local_handles: Vec::new(),
}, },
copilot_enabled: Copilot::global(cx).is_some(), copilot_lsp_subscription,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(), current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
} }
}) })
@ -696,6 +698,8 @@ impl Project {
let (tx, rx) = mpsc::unbounded(); let (tx, rx) = mpsc::unbounded();
cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx)) cx.spawn_weak(|this, cx| Self::send_buffer_ordered_messages(this, rx, cx))
.detach(); .detach();
let copilot_lsp_subscription =
Copilot::global(cx).map(|copilot| subscribe_for_copilot_events(&copilot, cx));
let mut this = Self { let mut this = Self {
worktrees: Vec::new(), worktrees: Vec::new(),
buffer_ordered_messages_tx: tx, buffer_ordered_messages_tx: tx,
@ -754,7 +758,7 @@ impl Project {
terminals: Terminals { terminals: Terminals {
local_handles: Vec::new(), local_handles: Vec::new(),
}, },
copilot_enabled: Copilot::global(cx).is_some(), copilot_lsp_subscription,
current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(), current_lsp_settings: settings::get::<ProjectSettings>(cx).lsp.clone(),
}; };
for worktree in worktrees { for worktree in worktrees {
@ -885,12 +889,14 @@ impl Project {
self.restart_language_servers(worktree, language, cx); self.restart_language_servers(worktree, language, cx);
} }
if !self.copilot_enabled && Copilot::global(cx).is_some() { if self.copilot_lsp_subscription.is_none() {
self.copilot_enabled = true; if let Some(copilot) = Copilot::global(cx) {
for buffer in self.opened_buffers.values() { for buffer in self.opened_buffers.values() {
if let Some(buffer) = buffer.upgrade(cx) { if let Some(buffer) = buffer.upgrade(cx) {
self.register_buffer_with_copilot(&buffer, 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.detect_language_for_buffer(buffer, cx);
self.register_buffer_with_language_servers(buffer, cx); self.register_buffer_with_language_servers(buffer, cx);
self.register_buffer_with_copilot(buffer, cx); self.register_buffer_with_copilot(buffer, cx);
self.register_copilot_language_server(cx);
cx.observe_release(buffer, |this, buffer, cx| { cx.observe_release(buffer, |this, buffer, cx| {
if let Some(file) = File::from_dyn(buffer.file()) { if let Some(file) = File::from_dyn(buffer.file()) {
if file.is_local() { if file.is_local() {
@ -2071,20 +2076,6 @@ 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( async fn send_buffer_ordered_messages(
this: WeakModelHandle<Self>, this: WeakModelHandle<Self>,
rx: UnboundedReceiver<BufferOrderedMessage>, rx: UnboundedReceiver<BufferOrderedMessage>,
@ -8024,6 +8015,28 @@ impl Project {
} }
} }
fn subscribe_for_copilot_events(
copilot: &ModelHandle<Copilot>,
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 { fn glob_literal_prefix<'a>(glob: &'a str) -> &'a str {
let mut literal_end = 0; let mut literal_end = 0;
for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() { for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {