mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 05:15:00 +00:00
Update new buffers with existing diagnostics in Project – after assigning language
This commit is contained in:
parent
2773cab4ec
commit
8bf628c17b
2 changed files with 56 additions and 38 deletions
|
@ -489,20 +489,20 @@ impl Project {
|
||||||
path: impl Into<ProjectPath>,
|
path: impl Into<ProjectPath>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Task<Result<ModelHandle<Buffer>>> {
|
) -> Task<Result<ModelHandle<Buffer>>> {
|
||||||
let path = path.into();
|
let project_path = path.into();
|
||||||
let worktree = if let Some(worktree) = self.worktree_for_id(path.worktree_id, cx) {
|
let worktree = if let Some(worktree) = self.worktree_for_id(project_path.worktree_id, cx) {
|
||||||
worktree
|
worktree
|
||||||
} else {
|
} else {
|
||||||
return Task::ready(Err(anyhow!("no such worktree")));
|
return Task::ready(Err(anyhow!("no such worktree")));
|
||||||
};
|
};
|
||||||
|
|
||||||
// If there is already a buffer for the given path, then return it.
|
// If there is already a buffer for the given path, then return it.
|
||||||
let existing_buffer = self.get_open_buffer(&path, cx);
|
let existing_buffer = self.get_open_buffer(&project_path, cx);
|
||||||
if let Some(existing_buffer) = existing_buffer {
|
if let Some(existing_buffer) = existing_buffer {
|
||||||
return Task::ready(Ok(existing_buffer));
|
return Task::ready(Ok(existing_buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut loading_watch = match self.loading_buffers.entry(path.clone()) {
|
let mut loading_watch = match self.loading_buffers.entry(project_path.clone()) {
|
||||||
// If the given path is already being loaded, then wait for that existing
|
// If the given path is already being loaded, then wait for that existing
|
||||||
// task to complete and return the same buffer.
|
// task to complete and return the same buffer.
|
||||||
hash_map::Entry::Occupied(e) => e.get().clone(),
|
hash_map::Entry::Occupied(e) => e.get().clone(),
|
||||||
|
@ -512,16 +512,15 @@ impl Project {
|
||||||
let (mut tx, rx) = postage::watch::channel();
|
let (mut tx, rx) = postage::watch::channel();
|
||||||
entry.insert(rx.clone());
|
entry.insert(rx.clone());
|
||||||
|
|
||||||
let load_buffer = worktree.update(cx, |worktree, cx| match worktree {
|
let load_buffer = worktree.update(cx, |worktree, cx| {
|
||||||
Worktree::Local(worktree) => worktree.open_buffer(&path.path, cx),
|
worktree.load_buffer(&project_path.path, cx)
|
||||||
Worktree::Remote(worktree) => worktree.open_buffer(&path.path, cx),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
cx.spawn(move |this, mut cx| async move {
|
cx.spawn(move |this, mut cx| async move {
|
||||||
let load_result = load_buffer.await;
|
let load_result = load_buffer.await;
|
||||||
*tx.borrow_mut() = Some(this.update(&mut cx, |this, cx| {
|
*tx.borrow_mut() = Some(this.update(&mut cx, |this, cx| {
|
||||||
// Record the fact that the buffer is no longer loading.
|
// Record the fact that the buffer is no longer loading.
|
||||||
this.loading_buffers.remove(&path);
|
this.loading_buffers.remove(&project_path);
|
||||||
let buffer = load_result.map_err(Arc::new)?;
|
let buffer = load_result.map_err(Arc::new)?;
|
||||||
this.open_buffers.insert(
|
this.open_buffers.insert(
|
||||||
buffer.read(cx).remote_id() as usize,
|
buffer.read(cx).remote_id() as usize,
|
||||||
|
@ -623,31 +622,46 @@ impl Project {
|
||||||
buffer: &ModelHandle<Buffer>,
|
buffer: &ModelHandle<Buffer>,
|
||||||
cx: &mut ModelContext<Self>,
|
cx: &mut ModelContext<Self>,
|
||||||
) -> Option<()> {
|
) -> Option<()> {
|
||||||
|
let (path, full_path) = {
|
||||||
|
let file = buffer.read(cx).file()?;
|
||||||
|
(file.path().clone(), file.full_path())
|
||||||
|
};
|
||||||
|
|
||||||
// Set the buffer's language
|
// Set the buffer's language
|
||||||
let full_path = buffer.read(cx).file()?.full_path();
|
|
||||||
let language = self.languages.select_language(&full_path)?.clone();
|
let language = self.languages.select_language(&full_path)?.clone();
|
||||||
buffer.update(cx, |buffer, cx| {
|
buffer.update(cx, |buffer, cx| {
|
||||||
buffer.set_language(Some(language.clone()), cx);
|
buffer.set_language(Some(language.clone()), cx);
|
||||||
});
|
});
|
||||||
|
|
||||||
// For local worktrees, start a language server if needed.
|
// For local worktrees, start a language server if needed.
|
||||||
|
// Also assign the language server and any previously stored diagnostics to the buffer.
|
||||||
let worktree = worktree.read(cx);
|
let worktree = worktree.read(cx);
|
||||||
let worktree_id = worktree.id();
|
if let Some(local_worktree) = worktree.as_local() {
|
||||||
let worktree_abs_path = worktree.as_local()?.abs_path().clone();
|
let worktree_id = local_worktree.id();
|
||||||
let language_server = match self
|
let diagnostics = local_worktree.diagnostics_for_path(&path);
|
||||||
.language_servers
|
let worktree_abs_path = local_worktree.abs_path().clone();
|
||||||
.entry((worktree_id, language.name().to_string()))
|
|
||||||
{
|
|
||||||
hash_map::Entry::Occupied(e) => Some(e.get().clone()),
|
|
||||||
hash_map::Entry::Vacant(e) => {
|
|
||||||
Self::start_language_server(self.client.clone(), language, &worktree_abs_path, cx)
|
|
||||||
.map(|server| e.insert(server).clone())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
buffer.update(cx, |buffer, cx| {
|
let language_server = match self
|
||||||
buffer.set_language_server(language_server, cx)
|
.language_servers
|
||||||
});
|
.entry((worktree_id, language.name().to_string()))
|
||||||
|
{
|
||||||
|
hash_map::Entry::Occupied(e) => Some(e.get().clone()),
|
||||||
|
hash_map::Entry::Vacant(e) => Self::start_language_server(
|
||||||
|
self.client.clone(),
|
||||||
|
language,
|
||||||
|
&worktree_abs_path,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.map(|server| e.insert(server).clone()),
|
||||||
|
};
|
||||||
|
|
||||||
|
buffer.update(cx, |buffer, cx| {
|
||||||
|
buffer.set_language_server(language_server, cx);
|
||||||
|
if let Some(diagnostics) = diagnostics {
|
||||||
|
buffer.update_diagnostics(None, diagnostics, cx).log_err();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,6 +347,17 @@ impl Worktree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn load_buffer(
|
||||||
|
&mut self,
|
||||||
|
path: &Path,
|
||||||
|
cx: &mut ModelContext<Self>,
|
||||||
|
) -> Task<Result<ModelHandle<Buffer>>> {
|
||||||
|
match self {
|
||||||
|
Worktree::Local(worktree) => worktree.load_buffer(path, cx),
|
||||||
|
Worktree::Remote(worktree) => worktree.load_buffer(path, cx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn diagnostic_summaries<'a>(
|
pub fn diagnostic_summaries<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
) -> impl Iterator<Item = (Arc<Path>, DiagnosticSummary)> + 'a {
|
) -> impl Iterator<Item = (Arc<Path>, DiagnosticSummary)> + 'a {
|
||||||
|
@ -536,7 +547,7 @@ impl LocalWorktree {
|
||||||
self.config.collaborators.clone()
|
self.config.collaborators.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn open_buffer(
|
pub(crate) fn load_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
cx: &mut ModelContext<Worktree>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
@ -546,21 +557,14 @@ impl LocalWorktree {
|
||||||
let (file, contents) = this
|
let (file, contents) = this
|
||||||
.update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx))
|
.update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx))
|
||||||
.await?;
|
.await?;
|
||||||
|
Ok(cx.add_model(|cx| Buffer::from_file(0, contents, Box::new(file), cx)))
|
||||||
let diagnostics = this.update(&mut cx, |this, _| {
|
|
||||||
this.as_local_mut().unwrap().diagnostics.get(&path).cloned()
|
|
||||||
});
|
|
||||||
|
|
||||||
Ok(cx.add_model(|cx| {
|
|
||||||
let mut buffer = Buffer::from_file(0, contents, Box::new(file), cx);
|
|
||||||
if let Some(diagnostics) = diagnostics {
|
|
||||||
buffer.update_diagnostics(None, diagnostics, cx).unwrap();
|
|
||||||
}
|
|
||||||
buffer
|
|
||||||
}))
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn diagnostics_for_path(&self, path: &Path) -> Option<Vec<DiagnosticEntry<PointUtf16>>> {
|
||||||
|
self.diagnostics.get(path).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update_diagnostics(
|
pub fn update_diagnostics(
|
||||||
&mut self,
|
&mut self,
|
||||||
worktree_path: Arc<Path>,
|
worktree_path: Arc<Path>,
|
||||||
|
@ -798,7 +802,7 @@ impl LocalWorktree {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteWorktree {
|
impl RemoteWorktree {
|
||||||
pub(crate) fn open_buffer(
|
pub(crate) fn load_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
cx: &mut ModelContext<Worktree>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
|
|
Loading…
Reference in a new issue