mirror of
https://github.com/Myriad-Dreamin/tinymist.git
synced 2025-11-23 12:46:43 +00:00
fix: emit save events to cover issue of notify (#2006)
This commit is contained in:
parent
58b43c006c
commit
7455d11629
3 changed files with 52 additions and 1 deletions
|
|
@ -243,6 +243,8 @@ pub enum Interrupt<F: CompilerFeat> {
|
||||||
Memory(MemoryEvent),
|
Memory(MemoryEvent),
|
||||||
/// File system event.
|
/// File system event.
|
||||||
Fs(FilesystemEvent),
|
Fs(FilesystemEvent),
|
||||||
|
/// Save a file.
|
||||||
|
Save(ImmutPath),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: CompilerFeat> fmt::Debug for Interrupt<F> {
|
impl<F: CompilerFeat> fmt::Debug for Interrupt<F> {
|
||||||
|
|
@ -258,6 +260,7 @@ impl<F: CompilerFeat> fmt::Debug for Interrupt<F> {
|
||||||
Interrupt::CreationTimestamp(ts) => write!(f, "CreationTimestamp({ts:?})"),
|
Interrupt::CreationTimestamp(ts) => write!(f, "CreationTimestamp({ts:?})"),
|
||||||
Interrupt::Memory(..) => write!(f, "Memory(..)"),
|
Interrupt::Memory(..) => write!(f, "Memory(..)"),
|
||||||
Interrupt::Fs(..) => write!(f, "Fs(..)"),
|
Interrupt::Fs(..) => write!(f, "Fs(..)"),
|
||||||
|
Interrupt::Save(path) => write!(f, "Save({path:?})"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -624,6 +627,23 @@ impl<F: CompilerFeat + Send + Sync + 'static, Ext: Default + 'static> ProjectCom
|
||||||
let err = self.dep_tx.send(event);
|
let err = self.dep_tx.send(event);
|
||||||
log_send_error("dep_tx", err);
|
log_send_error("dep_tx", err);
|
||||||
}
|
}
|
||||||
|
Interrupt::Save(event) => {
|
||||||
|
let changes = std::iter::repeat_n(&event, 1 + self.dedicates.len());
|
||||||
|
let proj = std::iter::once(&mut self.primary).chain(self.dedicates.iter_mut());
|
||||||
|
|
||||||
|
for (proj, saved_path) in proj.zip(changes) {
|
||||||
|
log::debug!(
|
||||||
|
"ProjectCompiler({}, rev={}): save changes",
|
||||||
|
proj.verse.revision.get(),
|
||||||
|
proj.id
|
||||||
|
);
|
||||||
|
|
||||||
|
// todo: only emit if saved_path is related
|
||||||
|
let _ = saved_path;
|
||||||
|
|
||||||
|
proj.reason.merge(reason_by_fs());
|
||||||
|
}
|
||||||
|
}
|
||||||
Interrupt::Fs(event) => {
|
Interrupt::Fs(event) => {
|
||||||
log::debug!("ProjectCompiler: fs event incoming {event:?}");
|
log::debug!("ProjectCompiler: fs event incoming {event:?}");
|
||||||
|
|
||||||
|
|
@ -634,6 +654,12 @@ impl<F: CompilerFeat + Send + Sync + 'static, Ext: Default + 'static> ProjectCom
|
||||||
let proj = std::iter::once(&mut self.primary).chain(self.dedicates.iter_mut());
|
let proj = std::iter::once(&mut self.primary).chain(self.dedicates.iter_mut());
|
||||||
|
|
||||||
for (proj, changes) in proj.zip(changes) {
|
for (proj, changes) in proj.zip(changes) {
|
||||||
|
log::debug!(
|
||||||
|
"ProjectCompiler({}, rev={}): fs changes applying",
|
||||||
|
proj.verse.revision.get(),
|
||||||
|
proj.id
|
||||||
|
);
|
||||||
|
|
||||||
proj.verse.increment_revision(|verse| {
|
proj.verse.increment_revision(|verse| {
|
||||||
let mut vfs = verse.vfs();
|
let mut vfs = verse.vfs();
|
||||||
|
|
||||||
|
|
@ -650,6 +676,12 @@ impl<F: CompilerFeat + Send + Sync + 'static, Ext: Default + 'static> ProjectCom
|
||||||
vfs.notify_fs_changes(changes);
|
vfs.notify_fs_changes(changes);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
log::debug!(
|
||||||
|
"ProjectCompiler({},rev={}): fs changes applied, {is_sync}",
|
||||||
|
proj.id,
|
||||||
|
proj.verse.revision.get(),
|
||||||
|
);
|
||||||
|
|
||||||
if !self.ignore_first_sync || !is_sync {
|
if !self.ignore_first_sync || !is_sync {
|
||||||
proj.reason.merge(reason_by_fs());
|
proj.reason.merge(reason_by_fs());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,22 @@ impl ServerState {
|
||||||
self.update_sources(files)
|
self.update_sources(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Saves a source file.
|
||||||
|
pub fn save_source(&mut self, path: ImmutPath) -> Result<()> {
|
||||||
|
// FIXME: this is a workaround for the issue of notify, which does not fully
|
||||||
|
// emit fs changes.
|
||||||
|
//
|
||||||
|
// The case to fix:
|
||||||
|
// When editing a file, the last compilation sync deps to notify actor (rev=N-1,
|
||||||
|
// actual state=S). At the time, the next fs change comes, and notifier actor
|
||||||
|
// reads the change (notify state=S'). Next, another fs change comes (rev=N,
|
||||||
|
// actual state=S'). However, since the notifier actor read the state
|
||||||
|
// earlier (notify state=S'), the actor will not emit a change at rev N, bang...
|
||||||
|
self.project.interrupt(Interrupt::Save(path));
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Queries a source file that must be in memory.
|
/// Queries a source file that must be in memory.
|
||||||
pub fn query_source<T>(
|
pub fn query_source<T>(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
||||||
|
|
@ -113,7 +113,10 @@ impl ServerState {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn did_save(&mut self, _params: DidSaveTextDocumentParams) -> LspResult<()> {
|
pub(crate) fn did_save(&mut self, params: DidSaveTextDocumentParams) -> LspResult<()> {
|
||||||
|
let path = as_path_(params.text_document.uri).as_path().into();
|
||||||
|
self.save_source(path).map_err(invalid_params)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue