aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_vfs/src/lib.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/lib.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/lib.rs')
-rw-r--r--crates/ra_vfs/src/lib.rs165
1 files changed, 124 insertions, 41 deletions
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs
index 889ed788d..2930f6b80 100644
--- a/crates/ra_vfs/src/lib.rs
+++ b/crates/ra_vfs/src/lib.rs
@@ -75,6 +75,7 @@ impl_arena_id!(VfsFile);
75struct VfsFileData { 75struct VfsFileData {
76 root: VfsRoot, 76 root: VfsRoot,
77 path: RelativePathBuf, 77 path: RelativePathBuf,
78 is_overlayed: bool,
78 text: Arc<String>, 79 text: Arc<String>,
79} 80}
80 81
@@ -170,7 +171,7 @@ impl Vfs {
170 } else { 171 } else {
171 let text = fs::read_to_string(path).unwrap_or_default(); 172 let text = fs::read_to_string(path).unwrap_or_default();
172 let text = Arc::new(text); 173 let text = Arc::new(text);
173 let file = self.add_file(root, rel_path.clone(), Arc::clone(&text)); 174 let file = self.add_file(root, rel_path.clone(), Arc::clone(&text), false);
174 let change = VfsChange::AddFile { 175 let change = VfsChange::AddFile {
175 file, 176 file,
176 text, 177 text,
@@ -205,7 +206,7 @@ impl Vfs {
205 continue; 206 continue;
206 } 207 }
207 let text = Arc::new(text); 208 let text = Arc::new(text);
208 let file = self.add_file(task.root, path.clone(), Arc::clone(&text)); 209 let file = self.add_file(task.root, path.clone(), Arc::clone(&text), false);
209 files.push((file, path, text)); 210 files.push((file, path, text));
210 } 211 }
211 212
@@ -215,63 +216,132 @@ impl Vfs {
215 }; 216 };
216 self.pending_changes.push(change); 217 self.pending_changes.push(change);
217 } 218 }
218 io::TaskResult::WatcherChange(change) => { 219 io::TaskResult::HandleChange(change) => match &change {
219 // TODO 220 watcher::WatcherChange::Create(path)
220 unimplemented!() 221 | watcher::WatcherChange::Remove(path)
222 | watcher::WatcherChange::Write(path) => {
223 if self.should_handle_change(&path) {
224 self.worker.inp.send(io::Task::LoadChange(change)).unwrap()
225 }
226 }
227 watcher::WatcherChange::Rescan => {
228 // TODO send Task::AddRoot?
229 }
230 },
231 io::TaskResult::LoadChange(None) => {}
232 io::TaskResult::LoadChange(Some(change)) => match change {
233 io::WatcherChangeData::Create { path, text }
234 | io::WatcherChangeData::Write { path, text } => {
235 if let Some((root, path, file)) = self.find_root(&path) {
236 if let Some(file) = file {
237 self.do_change_file(file, text, false);
238 } else {
239 self.do_add_file(root, path, text, false);
240 }
241 }
242 }
243 io::WatcherChangeData::Remove { path } => {
244 if let Some((root, path, file)) = self.find_root(&path) {
245 if let Some(file) = file {
246 self.do_remove_file(root, path, file, false);
247 }
248 }
249 }
250 },
251 }
252 }
253
254 fn should_handle_change(&self, path: &Path) -> bool {
255 if let Some((_root, _rel_path, file)) = self.find_root(&path) {
256 if let Some(file) = file {
257 if self.files[file].is_overlayed {
258 // file is overlayed
259 return false;
260 }
221 } 261 }
262 true
263 } else {
264 // file doesn't belong to any root
265 false
222 } 266 }
223 } 267 }
224 268
269 fn do_add_file(
270 &mut self,
271 root: VfsRoot,
272 path: RelativePathBuf,
273 text: String,
274 is_overlay: bool,
275 ) -> Option<VfsFile> {
276 let text = Arc::new(text);
277 let file = self.add_file(root, path.clone(), text.clone(), is_overlay);
278 self.pending_changes.push(VfsChange::AddFile {
279 file,
280 root,
281 path,
282 text,
283 });
284 Some(file)
285 }
286
287 fn do_change_file(&mut self, file: VfsFile, text: String, is_overlay: bool) {
288 if !is_overlay && self.files[file].is_overlayed {
289 return;
290 }
291 let text = Arc::new(text);
292 self.change_file(file, text.clone(), is_overlay);
293 self.pending_changes
294 .push(VfsChange::ChangeFile { file, text });
295 }
296
297 fn do_remove_file(
298 &mut self,
299 root: VfsRoot,
300 path: RelativePathBuf,
301 file: VfsFile,
302 is_overlay: bool,
303 ) {
304 if !is_overlay && self.files[file].is_overlayed {
305 return;
306 }
307 self.remove_file(file);
308 self.pending_changes
309 .push(VfsChange::RemoveFile { root, path, file });
310 }
311
225 pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { 312 pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> {
226 let mut res = None;
227 if let Some((root, rel_path, file)) = self.find_root(path) { 313 if let Some((root, rel_path, file)) = self.find_root(path) {
228 let text = Arc::new(text); 314 if let Some(file) = file {
229 let change = if let Some(file) = file { 315 self.do_change_file(file, text, true);
230 res = Some(file); 316 Some(file)
231 self.change_file(file, Arc::clone(&text));
232 VfsChange::ChangeFile { file, text }
233 } else { 317 } else {
234 let file = self.add_file(root, rel_path.clone(), Arc::clone(&text)); 318 self.do_add_file(root, rel_path, text, true)
235 res = Some(file); 319 }
236 VfsChange::AddFile { 320 } else {
237 file, 321 None
238 text,
239 root,
240 path: rel_path,
241 }
242 };
243 self.pending_changes.push(change);
244 } 322 }
245 res
246 } 323 }
247 324
248 pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { 325 pub fn change_file_overlay(&mut self, path: &Path, new_text: String) {
249 if let Some((_root, _path, file)) = self.find_root(path) { 326 if let Some((_root, _path, file)) = self.find_root(path) {
250 let file = file.expect("can't change a file which wasn't added"); 327 let file = file.expect("can't change a file which wasn't added");
251 let text = Arc::new(new_text); 328 self.do_change_file(file, new_text, true);
252 self.change_file(file, Arc::clone(&text));
253 let change = VfsChange::ChangeFile { file, text };
254 self.pending_changes.push(change);
255 } 329 }
256 } 330 }
257 331
258 pub fn remove_file_overlay(&mut self, path: &Path) -> Option<VfsFile> { 332 pub fn remove_file_overlay(&mut self, path: &Path) -> Option<VfsFile> {
259 let mut res = None;
260 if let Some((root, path, file)) = self.find_root(path) { 333 if let Some((root, path, file)) = self.find_root(path) {
261 let file = file.expect("can't remove a file which wasn't added"); 334 let file = file.expect("can't remove a file which wasn't added");
262 res = Some(file);
263 let full_path = path.to_path(&self.roots[root].root); 335 let full_path = path.to_path(&self.roots[root].root);
264 let change = if let Ok(text) = fs::read_to_string(&full_path) { 336 if let Ok(text) = fs::read_to_string(&full_path) {
265 let text = Arc::new(text); 337 self.do_change_file(file, text, true);
266 self.change_file(file, Arc::clone(&text));
267 VfsChange::ChangeFile { file, text }
268 } else { 338 } else {
269 self.remove_file(file); 339 self.do_remove_file(root, path, file, true);
270 VfsChange::RemoveFile { root, file, path } 340 }
271 }; 341 Some(file)
272 self.pending_changes.push(change); 342 } else {
343 None
273 } 344 }
274 res
275 } 345 }
276 346
277 pub fn commit_changes(&mut self) -> Vec<VfsChange> { 347 pub fn commit_changes(&mut self) -> Vec<VfsChange> {
@@ -285,15 +355,28 @@ impl Vfs {
285 self.worker_handle.shutdown() 355 self.worker_handle.shutdown()
286 } 356 }
287 357
288 fn add_file(&mut self, root: VfsRoot, path: RelativePathBuf, text: Arc<String>) -> VfsFile { 358 fn add_file(
289 let data = VfsFileData { root, path, text }; 359 &mut self,
360 root: VfsRoot,
361 path: RelativePathBuf,
362 text: Arc<String>,
363 is_overlayed: bool,
364 ) -> VfsFile {
365 let data = VfsFileData {
366 root,
367 path,
368 text,
369 is_overlayed,
370 };
290 let file = self.files.alloc(data); 371 let file = self.files.alloc(data);
291 self.root2files.get_mut(&root).unwrap().insert(file); 372 self.root2files.get_mut(&root).unwrap().insert(file);
292 file 373 file
293 } 374 }
294 375
295 fn change_file(&mut self, file: VfsFile, new_text: Arc<String>) { 376 fn change_file(&mut self, file: VfsFile, new_text: Arc<String>, is_overlayed: bool) {
296 self.files[file].text = new_text; 377 let mut file_data = &mut self.files[file];
378 file_data.text = new_text;
379 file_data.is_overlayed = is_overlayed;
297 } 380 }
298 381
299 fn remove_file(&mut self, file: VfsFile) { 382 fn remove_file(&mut self, file: VfsFile) {