Supermaven (#10788)

Adds a supermaven provider for completions. There are various other
refactors amidst this branch, primarily to make copilot no longer a
dependency of project as well as show LSP Logs for global LSPs like
copilot properly.

This feature is not enabled by default. We're going to seek to refine it
in the coming weeks.

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan Sobo <nathan@zed.dev>
Co-authored-by: Max <max@zed.dev>
Co-authored-by: Max Brunsfeld <maxbrunsfeld@gmail.com>
This commit is contained in:
Kyle Kelley 2024-05-03 12:50:42 -07:00 committed by GitHub
parent 610968815c
commit 6563330239
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
47 changed files with 2242 additions and 827 deletions

View file

@ -20,7 +20,6 @@ use client::{
};
use clock::ReplicaId;
use collections::{hash_map, BTreeMap, HashMap, HashSet, VecDeque};
use copilot::Copilot;
use debounced_delay::DebouncedDelay;
use futures::{
channel::{
@ -200,8 +199,6 @@ pub struct Project {
_maintain_buffer_languages: Task<()>,
_maintain_workspace_config: Task<Result<()>>,
terminals: Terminals,
copilot_lsp_subscription: Option<gpui::Subscription>,
copilot_log_subscription: Option<lsp::Subscription>,
current_lsp_settings: HashMap<Arc<str>, LspSettings>,
node: Option<Arc<dyn NodeRuntime>>,
default_prettier: DefaultPrettier,
@ -685,8 +682,6 @@ impl Project {
let (tx, rx) = mpsc::unbounded();
cx.spawn(move |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 tasks = Inventory::new(cx);
Self {
@ -735,8 +730,6 @@ impl Project {
terminals: Terminals {
local_handles: Vec::new(),
},
copilot_lsp_subscription,
copilot_log_subscription: None,
current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
node: Some(node),
default_prettier: DefaultPrettier::default(),
@ -823,8 +816,6 @@ impl Project {
let (tx, rx) = mpsc::unbounded();
cx.spawn(move |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,
@ -891,8 +882,6 @@ impl Project {
terminals: Terminals {
local_handles: Vec::new(),
},
copilot_lsp_subscription,
copilot_log_subscription: None,
current_lsp_settings: ProjectSettings::get_global(cx).lsp.clone(),
node: None,
default_prettier: DefaultPrettier::default(),
@ -1184,17 +1173,6 @@ impl Project {
self.restart_language_servers(worktree, language, 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() {
self.register_buffer_with_copilot(&buffer, cx);
}
}
self.copilot_lsp_subscription = Some(subscribe_for_copilot_events(&copilot, cx));
}
}
cx.notify();
}
@ -2351,7 +2329,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_buffer_with_copilot(buffer, cx);
cx.observe_release(buffer, |this, buffer, cx| {
if let Some(file) = File::from_dyn(buffer.file()) {
if file.is_local() {
@ -2500,15 +2478,15 @@ impl Project {
});
}
fn register_buffer_with_copilot(
&self,
buffer_handle: &Model<Buffer>,
cx: &mut ModelContext<Self>,
) {
if let Some(copilot) = Copilot::global(cx) {
copilot.update(cx, |copilot, cx| copilot.register_buffer(buffer_handle, cx));
}
}
// fn register_buffer_with_copilot(
// &self,
// buffer_handle: &Model<Buffer>,
// cx: &mut ModelContext<Self>,
// ) {
// if let Some(copilot) = Copilot::global(cx) {
// copilot.update(cx, |copilot, cx| copilot.register_buffer(buffer_handle, cx));
// }
// }
async fn send_buffer_ordered_messages(
this: WeakModel<Self>,
@ -10475,43 +10453,6 @@ async fn search_ignored_entry(
}
}
fn subscribe_for_copilot_events(
copilot: &Model<Copilot>,
cx: &mut ModelContext<'_, Project>,
) -> gpui::Subscription {
cx.subscribe(
copilot,
|project, copilot, copilot_event, cx| match copilot_event {
copilot::Event::CopilotLanguageServerStarted => {
match copilot.read(cx).language_server() {
Some((name, copilot_server)) => {
// Another event wants to re-add the server that was already added and subscribed to, avoid doing it again.
if !copilot_server.has_notification_handler::<copilot::request::LogMessage>() {
let new_server_id = copilot_server.server_id();
let weak_project = cx.weak_model();
let copilot_log_subscription = copilot_server
.on_notification::<copilot::request::LogMessage, _>(
move |params, mut cx| {
weak_project.update(&mut cx, |_, cx| {
cx.emit(Event::LanguageServerLog(
new_server_id,
params.message,
));
}).ok();
},
);
project.supplementary_language_servers.insert(new_server_id, (name.clone(), Arc::clone(copilot_server)));
project.copilot_log_subscription = Some(copilot_log_subscription);
cx.emit(Event::LanguageServerAdded(new_server_id));
}
}
None => debug_panic!("Received Copilot language server started event, but no language server is running"),
}
}
},
)
}
fn glob_literal_prefix(glob: &str) -> &str {
let mut literal_end = 0;
for (i, part) in glob.split(path::MAIN_SEPARATOR).enumerate() {