diff options
Diffstat (limited to 'crates/ra_vfs/src/watcher.rs')
-rw-r--r-- | crates/ra_vfs/src/watcher.rs | 85 |
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 | ||
8 | use crate::io; | ||
8 | use crossbeam_channel::Sender; | 9 | use crossbeam_channel::Sender; |
9 | use drop_bomb::DropBomb; | 10 | use drop_bomb::DropBomb; |
10 | use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; | 11 | use notify::{DebouncedEvent, RecommendedWatcher, RecursiveMode, Watcher as NotifyWatcher}; |
11 | use crate::{has_rs_extension, io}; | ||
12 | 12 | ||
13 | pub struct Watcher { | 13 | pub 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 | ||
28 | impl WatcherChange { | 27 | fn 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 | ||
79 | impl Watcher { | 61 | impl 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 { |