mirror of
https://github.com/zed-industries/zed.git
synced 2024-12-26 10:40:54 +00:00
Start on copilot completions
This commit is contained in:
parent
8ba9e63ab8
commit
180371929b
3 changed files with 72 additions and 3 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -1340,6 +1340,7 @@ dependencies = [
|
||||||
"client",
|
"client",
|
||||||
"futures 0.3.25",
|
"futures 0.3.25",
|
||||||
"gpui",
|
"gpui",
|
||||||
|
"language",
|
||||||
"log",
|
"log",
|
||||||
"lsp",
|
"lsp",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -10,6 +10,7 @@ doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
gpui = { path = "../gpui" }
|
gpui = { path = "../gpui" }
|
||||||
|
language = { path = "../language" }
|
||||||
settings = { path = "../settings" }
|
settings = { path = "../settings" }
|
||||||
lsp = { path = "../lsp" }
|
lsp = { path = "../lsp" }
|
||||||
util = { path = "../util" }
|
util = { path = "../util" }
|
||||||
|
|
|
@ -4,6 +4,7 @@ use anyhow::{anyhow, Result};
|
||||||
use async_compression::futures::bufread::GzipDecoder;
|
use async_compression::futures::bufread::GzipDecoder;
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use gpui::{actions, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task};
|
use gpui::{actions, AppContext, Entity, ModelContext, ModelHandle, MutableAppContext, Task};
|
||||||
|
use language::{Buffer, ToPointUtf16};
|
||||||
use lsp::LanguageServer;
|
use lsp::LanguageServer;
|
||||||
use smol::{fs, io::BufReader, stream::StreamExt};
|
use smol::{fs, io::BufReader, stream::StreamExt};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -38,7 +39,7 @@ pub fn init(client: Arc<Client>, cx: &mut MutableAppContext) {
|
||||||
|
|
||||||
enum CopilotServer {
|
enum CopilotServer {
|
||||||
Downloading,
|
Downloading,
|
||||||
Error(String),
|
Error(Arc<str>),
|
||||||
Started {
|
Started {
|
||||||
server: Arc<LanguageServer>,
|
server: Arc<LanguageServer>,
|
||||||
status: SignInStatus,
|
status: SignInStatus,
|
||||||
|
@ -59,6 +60,21 @@ pub enum Event {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Status {
|
||||||
|
Downloading,
|
||||||
|
Error(Arc<str>),
|
||||||
|
SignedOut,
|
||||||
|
Unauthorized,
|
||||||
|
Authorized,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Status {
|
||||||
|
fn is_authorized(&self) -> bool {
|
||||||
|
matches!(self, Status::Authorized)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Copilot {
|
struct Copilot {
|
||||||
server: CopilotServer,
|
server: CopilotServer,
|
||||||
}
|
}
|
||||||
|
@ -70,7 +86,12 @@ impl Entity for Copilot {
|
||||||
impl Copilot {
|
impl Copilot {
|
||||||
fn global(cx: &AppContext) -> Option<ModelHandle<Self>> {
|
fn global(cx: &AppContext) -> Option<ModelHandle<Self>> {
|
||||||
if cx.has_global::<ModelHandle<Self>>() {
|
if cx.has_global::<ModelHandle<Self>>() {
|
||||||
Some(cx.global::<ModelHandle<Self>>().clone())
|
let copilot = cx.global::<ModelHandle<Self>>().clone();
|
||||||
|
if copilot.read(cx).status().is_authorized() {
|
||||||
|
Some(copilot)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -103,7 +124,7 @@ impl Copilot {
|
||||||
this.update_sign_in_status(status, cx);
|
this.update_sign_in_status(status, cx);
|
||||||
}
|
}
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
this.server = CopilotServer::Error(error.to_string());
|
this.server = CopilotServer::Error(error.to_string().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -163,6 +184,35 @@ impl Copilot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn completions<T>(
|
||||||
|
&self,
|
||||||
|
buffer: &ModelHandle<Buffer>,
|
||||||
|
position: T,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> Task<Result<()>>
|
||||||
|
where
|
||||||
|
T: ToPointUtf16,
|
||||||
|
{
|
||||||
|
let server = match self.authenticated_server() {
|
||||||
|
Ok(server) => server,
|
||||||
|
Err(error) => return Task::ready(Err(error)),
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.spawn(|this, cx| async move { anyhow::Ok(()) })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn status(&self) -> Status {
|
||||||
|
match &self.server {
|
||||||
|
CopilotServer::Downloading => Status::Downloading,
|
||||||
|
CopilotServer::Error(error) => Status::Error(error.clone()),
|
||||||
|
CopilotServer::Started { status, .. } => match status {
|
||||||
|
SignInStatus::Authorized { .. } => Status::Authorized,
|
||||||
|
SignInStatus::Unauthorized { .. } => Status::Unauthorized,
|
||||||
|
SignInStatus::SignedOut => Status::SignedOut,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn update_sign_in_status(
|
fn update_sign_in_status(
|
||||||
&mut self,
|
&mut self,
|
||||||
lsp_status: request::SignInStatus,
|
lsp_status: request::SignInStatus,
|
||||||
|
@ -181,6 +231,23 @@ impl Copilot {
|
||||||
cx.notify();
|
cx.notify();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn authenticated_server(&self) -> Result<Arc<LanguageServer>> {
|
||||||
|
match &self.server {
|
||||||
|
CopilotServer::Downloading => Err(anyhow!("copilot is still downloading")),
|
||||||
|
CopilotServer::Error(error) => Err(anyhow!(
|
||||||
|
"copilot was not started because of an error: {}",
|
||||||
|
error
|
||||||
|
)),
|
||||||
|
CopilotServer::Started { server, status } => {
|
||||||
|
if matches!(status, SignInStatus::Authorized { .. }) {
|
||||||
|
Ok(server.clone())
|
||||||
|
} else {
|
||||||
|
Err(anyhow!("must sign in before using copilot"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_lsp_binary(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
async fn get_lsp_binary(http: Arc<dyn HttpClient>) -> anyhow::Result<PathBuf> {
|
||||||
|
|
Loading…
Reference in a new issue