Assign buffer's completion triggers from LSP capabilities

Also, make LanguageServer::new() async. The future resolves
once the server is initialized.
This commit is contained in:
Max Brunsfeld 2022-03-08 17:41:52 -08:00
parent 317a1bb07b
commit 4cb4b99c56
8 changed files with 345 additions and 368 deletions

View file

@ -203,79 +203,6 @@ pub trait LocalFile: File {
);
}
#[cfg(any(test, feature = "test-support"))]
pub struct FakeFile {
pub path: Arc<Path>,
}
#[cfg(any(test, feature = "test-support"))]
impl FakeFile {
pub fn new(path: impl AsRef<Path>) -> Self {
Self {
path: path.as_ref().into(),
}
}
}
#[cfg(any(test, feature = "test-support"))]
impl File for FakeFile {
fn as_local(&self) -> Option<&dyn LocalFile> {
Some(self)
}
fn mtime(&self) -> SystemTime {
SystemTime::UNIX_EPOCH
}
fn path(&self) -> &Arc<Path> {
&self.path
}
fn full_path(&self, _: &AppContext) -> PathBuf {
self.path.to_path_buf()
}
fn file_name(&self, _: &AppContext) -> OsString {
self.path.file_name().unwrap().to_os_string()
}
fn is_deleted(&self) -> bool {
false
}
fn save(
&self,
_: u64,
_: Rope,
_: clock::Global,
cx: &mut MutableAppContext,
) -> Task<Result<(clock::Global, SystemTime)>> {
cx.spawn(|_| async move { Ok((Default::default(), SystemTime::UNIX_EPOCH)) })
}
fn as_any(&self) -> &dyn Any {
self
}
fn to_proto(&self) -> rpc::proto::File {
unimplemented!()
}
}
#[cfg(any(test, feature = "test-support"))]
impl LocalFile for FakeFile {
fn abs_path(&self, _: &AppContext) -> PathBuf {
self.path.to_path_buf()
}
fn load(&self, cx: &AppContext) -> Task<Result<String>> {
cx.background().spawn(async move { Ok(Default::default()) })
}
fn buffer_reloaded(&self, _: u64, _: &clock::Global, _: SystemTime, _: &mut MutableAppContext) {
}
}
pub(crate) struct QueryCursorHandle(Option<QueryCursor>);
#[derive(Clone)]
@ -1435,8 +1362,21 @@ impl Buffer {
redone
}
pub fn set_completion_triggers(&mut self, triggers: Vec<String>, cx: &mut ModelContext<Self>) {
self.completion_triggers = triggers.clone();
let lamport_timestamp = self.text.lamport_clock.tick();
self.send_operation(
Operation::UpdateCompletionTriggers {
triggers,
lamport_timestamp,
},
cx,
);
cx.notify();
}
pub fn completion_triggers(&self) -> &[String] {
todo!()
&self.completion_triggers
}
}

View file

@ -247,29 +247,41 @@ impl LanguageRegistry {
cx: &mut MutableAppContext,
) -> Option<Task<Result<Arc<lsp::LanguageServer>>>> {
#[cfg(any(test, feature = "test-support"))]
if let Some(config) = &language.config.language_server {
if let Some(fake_config) = &config.fake_config {
let (server, mut fake_server) = lsp::LanguageServer::fake_with_capabilities(
fake_config.capabilities.clone(),
cx,
);
if language
.config
.language_server
.as_ref()
.and_then(|config| config.fake_config.as_ref())
.is_some()
{
let language = language.clone();
return Some(cx.spawn(|mut cx| async move {
let fake_config = language
.config
.language_server
.as_ref()
.unwrap()
.fake_config
.as_ref()
.unwrap();
let (server, mut fake_server) = cx
.update(|cx| {
lsp::LanguageServer::fake_with_capabilities(
fake_config.capabilities.clone(),
cx,
)
})
.await;
if let Some(initalizer) = &fake_config.initializer {
initalizer(&mut fake_server);
}
let servers_tx = fake_config.servers_tx.clone();
let initialized = server.capabilities();
cx.background()
.spawn(async move {
if initialized.await.is_some() {
servers_tx.unbounded_send(fake_server).ok();
}
})
.detach();
return Some(Task::ready(Ok(server.clone())));
}
fake_config
.servers_tx
.clone()
.unbounded_send(fake_server)
.ok();
Ok(server.clone())
}));
}
let download_dir = self
@ -310,7 +322,8 @@ impl LanguageRegistry {
adapter.initialization_options(),
&root_path,
background,
)?;
)
.await?;
Ok(server)
}))
}