aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_vfs')
-rw-r--r--crates/ra_vfs/src/io.rs19
-rw-r--r--crates/ra_vfs/src/lib.rs24
2 files changed, 28 insertions, 15 deletions
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs
index 0cffc03f3..8eb148a38 100644
--- a/crates/ra_vfs/src/io.rs
+++ b/crates/ra_vfs/src/io.rs
@@ -9,7 +9,7 @@ use relative_path::RelativePathBuf;
9use walkdir::WalkDir; 9use walkdir::WalkDir;
10use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher}; 10use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as _Watcher};
11 11
12use crate::{Roots, VfsRoot}; 12use crate::{Roots, VfsRoot, VfsTask};
13 13
14pub(crate) enum Task { 14pub(crate) enum Task {
15 AddRoot { root: VfsRoot }, 15 AddRoot { root: VfsRoot },
@@ -18,7 +18,7 @@ pub(crate) enum Task {
18/// `TaskResult` transfers files read on the IO thread to the VFS on the main 18/// `TaskResult` transfers files read on the IO thread to the VFS on the main
19/// thread. 19/// thread.
20#[derive(Debug)] 20#[derive(Debug)]
21pub enum TaskResult { 21pub(crate) enum TaskResult {
22 /// Emitted when we've recursively scanned a source root during the initial 22 /// Emitted when we've recursively scanned a source root during the initial
23 /// load. 23 /// load.
24 BulkLoadRoot { root: VfsRoot, files: Vec<(RelativePathBuf, String)> }, 24 BulkLoadRoot { root: VfsRoot, files: Vec<(RelativePathBuf, String)> },
@@ -46,7 +46,7 @@ enum ChangeKind {
46 46
47const WATCHER_DELAY: Duration = Duration::from_millis(250); 47const WATCHER_DELAY: Duration = Duration::from_millis(250);
48 48
49pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>; 49pub(crate) type Worker = thread_worker::Worker<Task, VfsTask>;
50pub(crate) fn start(roots: Arc<Roots>) -> Worker { 50pub(crate) fn start(roots: Arc<Roots>) -> Worker {
51 // This is a pretty elaborate setup of threads & channels! It is 51 // This is a pretty elaborate setup of threads & channels! It is
52 // explained by the following concerns: 52 // explained by the following concerns:
@@ -122,7 +122,7 @@ pub(crate) fn start(roots: Arc<Roots>) -> Worker {
122 122
123fn watch_root( 123fn watch_root(
124 watcher: Option<&mut RecommendedWatcher>, 124 watcher: Option<&mut RecommendedWatcher>,
125 sender: &Sender<TaskResult>, 125 sender: &Sender<VfsTask>,
126 roots: &Roots, 126 roots: &Roots,
127 root: VfsRoot, 127 root: VfsRoot,
128) { 128) {
@@ -136,7 +136,8 @@ fn watch_root(
136 Some((path, text)) 136 Some((path, text))
137 }) 137 })
138 .collect(); 138 .collect();
139 sender.send(TaskResult::BulkLoadRoot { root, files }).unwrap(); 139 let res = TaskResult::BulkLoadRoot { root, files };
140 sender.send(VfsTask(res)).unwrap();
140 log::debug!("... loaded {}", root_path.display()); 141 log::debug!("... loaded {}", root_path.display());
141} 142}
142 143
@@ -173,7 +174,7 @@ fn convert_notify_event(event: DebouncedEvent, sender: &Sender<(PathBuf, ChangeK
173 174
174fn handle_change( 175fn handle_change(
175 watcher: Option<&mut RecommendedWatcher>, 176 watcher: Option<&mut RecommendedWatcher>,
176 sender: &Sender<TaskResult>, 177 sender: &Sender<VfsTask>,
177 roots: &Roots, 178 roots: &Roots,
178 path: PathBuf, 179 path: PathBuf,
179 kind: ChangeKind, 180 kind: ChangeKind,
@@ -195,13 +196,15 @@ fn handle_change(
195 .try_for_each(|rel_path| { 196 .try_for_each(|rel_path| {
196 let abs_path = rel_path.to_path(&roots.path(root)); 197 let abs_path = rel_path.to_path(&roots.path(root));
197 let text = read_to_string(&abs_path); 198 let text = read_to_string(&abs_path);
198 sender.send(TaskResult::SingleFile { root, path: rel_path, text }) 199 let res = TaskResult::SingleFile { root, path: rel_path, text };
200 sender.send(VfsTask(res))
199 }) 201 })
200 .unwrap() 202 .unwrap()
201 } 203 }
202 ChangeKind::Write | ChangeKind::Remove => { 204 ChangeKind::Write | ChangeKind::Remove => {
203 let text = read_to_string(&path); 205 let text = read_to_string(&path);
204 sender.send(TaskResult::SingleFile { root, path: rel_path, text }).unwrap(); 206 let res = TaskResult::SingleFile { root, path: rel_path, text };
207 sender.send(VfsTask(res)).unwrap();
205 } 208 }
206 } 209 }
207} 210}
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index 8005c4ff8..3cd11c9f6 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -33,10 +33,20 @@ use crate::{
33 roots::Roots, 33 roots::Roots,
34}; 34};
35 35
36pub use crate::{ 36pub use crate::roots::VfsRoot;
37 io::TaskResult as VfsTask, 37
38 roots::VfsRoot, 38/// Opaque wrapper around file-system event.
39}; 39///
40/// Calling code is expected to just pass `VfsTask` to `handle_task` method. It
41/// is exposed as a public API so that the caller can plug vfs events into the
42/// main event loop and be notified when changes happen.
43pub struct VfsTask(TaskResult);
44
45impl fmt::Debug for VfsTask {
46 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47 f.write_str("VfsTask { ... }")
48 }
49}
40 50
41#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] 51#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
42pub struct VfsFile(pub u32); 52pub struct VfsFile(pub u32);
@@ -159,12 +169,12 @@ impl Vfs {
159 mem::replace(&mut self.pending_changes, Vec::new()) 169 mem::replace(&mut self.pending_changes, Vec::new())
160 } 170 }
161 171
162 pub fn task_receiver(&self) -> &Receiver<io::TaskResult> { 172 pub fn task_receiver(&self) -> &Receiver<VfsTask> {
163 self.worker.receiver() 173 self.worker.receiver()
164 } 174 }
165 175
166 pub fn handle_task(&mut self, task: io::TaskResult) { 176 pub fn handle_task(&mut self, task: VfsTask) {
167 match task { 177 match task.0 {
168 TaskResult::BulkLoadRoot { root, files } => { 178 TaskResult::BulkLoadRoot { root, files } => {
169 let mut cur_files = Vec::new(); 179 let mut cur_files = Vec::new();
170 // While we were scanning the root in the background, a file might have 180 // While we were scanning the root in the background, a file might have