aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs/src/watcher.rs
diff options
context:
space:
mode:
authorBernardo <[email protected]>2019-01-12 17:17:52 +0000
committerAleksey Kladov <[email protected]>2019-01-26 08:46:16 +0000
commit76bf7498aa88c4de4517f4eb1218807fdfc7071b (patch)
treee95b92ce0f54df298d59eb96450bd6bd06ba2939 /crates/ra_vfs/src/watcher.rs
parent6b86f038d61752bbf306ed5dd9def74be3b5dcc1 (diff)
handle watched events filtering in `Vfs`add `is_overlayed`load changed files contents in `io`
Diffstat (limited to 'crates/ra_vfs/src/watcher.rs')
-rw-r--r--crates/ra_vfs/src/watcher.rs85
1 files changed, 33 insertions, 52 deletions
diff --git a/crates/ra_vfs/src/watcher.rs b/crates/ra_vfs/src/watcher.rs
index a6d0496c0..a5401869c 100644
--- a/crates/ra_vfs/src/watcher.rs
+++ b/crates/ra_vfs/src/watcher.rs
@@ -5,10 +5,10 @@ use std::{
5 time::Duration, 5 time::Duration,
6}; 6};
7 7
8use crate::io;
8use crossbeam_channel::Sender; 9use crossbeam_channel::Sender;
9use drop_bomb::DropBomb; 10use drop_bomb::DropBomb;
10use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; 11use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher};
11use crate::{has_rs_extension, io};
12 12
13pub struct Watcher { 13pub struct Watcher {
14 watcher: RecommendedWatcher, 14 watcher: RecommendedWatcher,
@@ -21,59 +21,41 @@ pub enum WatcherChange {
21 Create(PathBuf), 21 Create(PathBuf),
22 Write(PathBuf), 22 Write(PathBuf),
23 Remove(PathBuf), 23 Remove(PathBuf),
24 // can this be replaced and use Remove and Create instead? 24 Rescan,
25 Rename(PathBuf, PathBuf),
26} 25}
27 26
28impl WatcherChange { 27fn send_change_events(
29 fn try_from_debounced_event(ev: DebouncedEvent) -> Option<WatcherChange> { 28 ev: DebouncedEvent,
30 match ev { 29 sender: &Sender<io::Task>,
31 DebouncedEvent::NoticeWrite(_) 30) -> Result<(), Box<std::error::Error>> {
32 | DebouncedEvent::NoticeRemove(_) 31 match ev {
33 | DebouncedEvent::Chmod(_) => { 32 DebouncedEvent::NoticeWrite(_)
34 // ignore 33 | DebouncedEvent::NoticeRemove(_)
35 None 34 | DebouncedEvent::Chmod(_) => {
36 } 35 // ignore
37 DebouncedEvent::Rescan => { 36 }
38 // TODO should we rescan the root? 37 DebouncedEvent::Rescan => {
39 None 38 sender.send(io::Task::LoadChange(WatcherChange::Rescan))?;
40 } 39 }
41 DebouncedEvent::Create(path) => { 40 DebouncedEvent::Create(path) => {
42 if has_rs_extension(&path) { 41 sender.send(io::Task::LoadChange(WatcherChange::Create(path)))?;
43 Some(WatcherChange::Create(path)) 42 }
44 } else { 43 DebouncedEvent::Write(path) => {
45 None 44 sender.send(io::Task::LoadChange(WatcherChange::Write(path)))?;
46 } 45 }
47 } 46 DebouncedEvent::Remove(path) => {
48 DebouncedEvent::Write(path) => { 47 sender.send(io::Task::LoadChange(WatcherChange::Remove(path)))?;
49 if has_rs_extension(&path) { 48 }
50 Some(WatcherChange::Write(path)) 49 DebouncedEvent::Rename(src, dst) => {
51 } else { 50 sender.send(io::Task::LoadChange(WatcherChange::Remove(src)))?;
52 None 51 sender.send(io::Task::LoadChange(WatcherChange::Create(dst)))?;
53 } 52 }
54 } 53 DebouncedEvent::Error(err, path) => {
55 DebouncedEvent::Remove(path) => { 54 // TODO should we reload the file contents?
56 if has_rs_extension(&path) { 55 log::warn!("watcher error {}, {:?}", err, path);
57 Some(WatcherChange::Remove(path))
58 } else {
59 None
60 }
61 }
62 DebouncedEvent::Rename(src, dst) => {
63 match (has_rs_extension(&src), has_rs_extension(&dst)) {
64 (true, true) => Some(WatcherChange::Rename(src, dst)),
65 (true, false) => Some(WatcherChange::Remove(src)),
66 (false, true) => Some(WatcherChange::Create(dst)),
67 (false, false) => None,
68 }
69 }
70 DebouncedEvent::Error(err, path) => {
71 // TODO should we reload the file contents?
72 log::warn!("watch error {}, {:?}", err, path);
73 None
74 }
75 } 56 }
76 } 57 }
58 Ok(())
77} 59}
78 60
79impl Watcher { 61impl Watcher {
@@ -86,8 +68,7 @@ impl Watcher {
86 input_receiver 68 input_receiver
87 .into_iter() 69 .into_iter()
88 // forward relevant events only 70 // forward relevant events only
89 .filter_map(WatcherChange::try_from_debounced_event) 71 .try_for_each(|change| send_change_events(change, &output_sender))
90 .try_for_each(|change| output_sender.send(io::Task::WatcherChange(change)))
91 .unwrap() 72 .unwrap()
92 }); 73 });
93 Ok(Watcher { 74 Ok(Watcher {