Skip to content

Commit 7820fb3

Browse files
committed
don't distinguish Create and Write events in VFS
1 parent 19718ea commit 7820fb3

File tree

2 files changed

+42
-38
lines changed

2 files changed

+42
-38
lines changed

crates/ra_vfs/src/io.rs

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,28 @@ pub(crate) enum Task {
1717
AddRoot { root: VfsRoot, config: Arc<RootConfig> },
1818
}
1919

20+
/// `TaskResult` transfers files read on the IO thread to the VFS on the main
21+
/// thread.
2022
#[derive(Debug)]
2123
pub enum TaskResult {
24+
/// Emitted when we've recursively scanned a source root during the initial
25+
/// load.
2226
BulkLoadRoot { root: VfsRoot, files: Vec<(RelativePathBuf, String)> },
23-
AddSingleFile { root: VfsRoot, path: RelativePathBuf, text: String },
24-
ChangeSingleFile { root: VfsRoot, path: RelativePathBuf, text: String },
25-
RemoveSingleFile { root: VfsRoot, path: RelativePathBuf },
27+
/// Emitted when we've noticed that a single file has changed.
28+
///
29+
/// Note that this by design does not distinguish between
30+
/// create/delete/write events, and instead specifies the *current* state of
31+
/// the file. The idea is to guarantee that in the quiescent state the sum
32+
/// of all results equals to the current state of the file system, while
33+
/// allowing to skip intermediate events in non-quiescent states.
34+
SingleFile { root: VfsRoot, path: RelativePathBuf, text: Option<String> },
2635
}
2736

37+
/// The kind of raw notification we've received from the notify library.
38+
///
39+
/// Note that these are not necessary 100% precise (for example we might receive
40+
/// `Create` instead of `Write`, see #734), but we try do distinguish `Create`s
41+
/// to implement recursive watching of directories.
2842
#[derive(Debug)]
2943
enum ChangeKind {
3044
Create,
@@ -45,7 +59,7 @@ impl Worker {
4559
// explained by the following concerns:
4660
// * we need to burn a thread translating from notify's mpsc to
4761
// crossbeam_channel.
48-
// * we want to read all files from a single thread, to gurantee that
62+
// * we want to read all files from a single thread, to guarantee that
4963
// we always get fresher versions and never go back in time.
5064
// * we want to tear down everything neatly during shutdown.
5165
let (worker, worker_handle) = thread_worker::spawn(
@@ -63,7 +77,7 @@ impl Worker {
6377
let mut watcher = notify::watcher(notify_sender, WATCHER_DELAY)
6478
.map_err(|e| log::error!("failed to spawn notify {}", e))
6579
.ok();
66-
// Start a silly thread to tranform between two channels
80+
// Start a silly thread to transform between two channels
6781
let thread = thread::spawn(move || {
6882
notify_receiver
6983
.into_iter()
@@ -98,7 +112,7 @@ impl Worker {
98112
}
99113
// Stopped the watcher
100114
drop(watcher.take());
101-
// Drain pending events: we are not inrerested in them anyways!
115+
// Drain pending events: we are not interested in them anyways!
102116
watcher_receiver.into_iter().for_each(|_| ());
103117

104118
let res = thread.join();
@@ -199,23 +213,16 @@ fn handle_change(
199213
}
200214
paths
201215
.into_iter()
202-
.filter_map(|rel_path| {
216+
.try_for_each(|rel_path| {
203217
let abs_path = rel_path.to_path(&config.root);
204-
let text = read_to_string(&abs_path)?;
205-
Some((rel_path, text))
206-
})
207-
.try_for_each(|(path, text)| {
208-
sender.send(TaskResult::AddSingleFile { root, path, text })
218+
let text = read_to_string(&abs_path);
219+
sender.send(TaskResult::SingleFile { root, path: rel_path, text })
209220
})
210221
.unwrap()
211222
}
212-
ChangeKind::Write => {
213-
if let Some(text) = read_to_string(&path) {
214-
sender.send(TaskResult::ChangeSingleFile { root, path: rel_path, text }).unwrap();
215-
}
216-
}
217-
ChangeKind::Remove => {
218-
sender.send(TaskResult::RemoveSingleFile { root, path: rel_path }).unwrap()
223+
ChangeKind::Write | ChangeKind::Remove => {
224+
let text = read_to_string(&path);
225+
sender.send(TaskResult::SingleFile { root, path: rel_path, text }).unwrap();
219226
}
220227
}
221228
}

crates/ra_vfs/src/lib.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ impl_arena_id!(VfsRoot);
3737

3838
/// Describes the contents of a single source root.
3939
///
40-
/// `RootConfig` can be thought of as a glob pattern like `src/**.rs` whihc
41-
/// specifes the source root or as a function whihc takes a `PathBuf` and
40+
/// `RootConfig` can be thought of as a glob pattern like `src/**.rs` which
41+
/// specifies the source root or as a function which takes a `PathBuf` and
4242
/// returns `true` iff path belongs to the source root
4343
pub(crate) struct RootConfig {
4444
root: PathBuf,
@@ -60,7 +60,7 @@ impl RootConfig {
6060
fn new(root: PathBuf, excluded_dirs: Vec<PathBuf>) -> RootConfig {
6161
RootConfig { root, excluded_dirs }
6262
}
63-
/// Cheks if root contains a path and returns a root-relative path.
63+
/// Checks if root contains a path and returns a root-relative path.
6464
pub(crate) fn contains(&self, path: &Path) -> Option<RelativePathBuf> {
6565
// First, check excluded dirs
6666
if self.excluded_dirs.iter().any(|it| path.starts_with(it)) {
@@ -210,7 +210,7 @@ impl Vfs {
210210
match task {
211211
TaskResult::BulkLoadRoot { root, files } => {
212212
let mut cur_files = Vec::new();
213-
// While we were scanning the root in the backgound, a file might have
213+
// While we were scanning the root in the background, a file might have
214214
// been open in the editor, so we need to account for that.
215215
let exising = self.root2files[root]
216216
.iter()
@@ -230,21 +230,18 @@ impl Vfs {
230230
let change = VfsChange::AddRoot { root, files: cur_files };
231231
self.pending_changes.push(change);
232232
}
233-
TaskResult::AddSingleFile { root, path, text } => {
234-
if self.find_file(root, &path).is_none() {
235-
self.do_add_file(root, path, text, false);
236-
}
237-
}
238-
TaskResult::ChangeSingleFile { root, path, text } => {
239-
if let Some(file) = self.find_file(root, &path) {
240-
self.do_change_file(file, text, false);
241-
} else {
242-
self.do_add_file(root, path, text, false);
243-
}
244-
}
245-
TaskResult::RemoveSingleFile { root, path } => {
246-
if let Some(file) = self.find_file(root, &path) {
247-
self.do_remove_file(root, path, file, false);
233+
TaskResult::SingleFile { root, path, text } => {
234+
match (self.find_file(root, &path), text) {
235+
(Some(file), None) => {
236+
self.do_remove_file(root, path, file, false);
237+
}
238+
(None, Some(text)) => {
239+
self.do_add_file(root, path, text, false);
240+
}
241+
(Some(file), Some(text)) => {
242+
self.do_change_file(file, text, false);
243+
}
244+
(None, None) => (),
248245
}
249246
}
250247
}

0 commit comments

Comments
 (0)