mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 22:01:37 +00:00
move watcher to io module
This commit is contained in:
parent
7f7c4e7465
commit
277e0f1baa
3 changed files with 29 additions and 31 deletions
|
@ -11,10 +11,11 @@ use relative_path::RelativePathBuf;
|
||||||
use thread_worker::WorkerHandle;
|
use thread_worker::WorkerHandle;
|
||||||
use walkdir::{DirEntry, WalkDir};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
use crate::{
|
mod watcher;
|
||||||
watcher::{Watcher, WatcherChange},
|
use watcher::Watcher;
|
||||||
VfsRoot,
|
pub use watcher::WatcherChange;
|
||||||
};
|
|
||||||
|
use crate::VfsRoot;
|
||||||
|
|
||||||
pub(crate) enum Task {
|
pub(crate) enum Task {
|
||||||
AddRoot {
|
AddRoot {
|
||||||
|
@ -22,6 +23,7 @@ pub(crate) enum Task {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
filter: Box<Fn(&DirEntry) -> bool + Send>,
|
filter: Box<Fn(&DirEntry) -> bool + Send>,
|
||||||
},
|
},
|
||||||
|
/// this variant should only be created by the watcher
|
||||||
HandleChange(WatcherChange),
|
HandleChange(WatcherChange),
|
||||||
LoadChange(WatcherChange),
|
LoadChange(WatcherChange),
|
||||||
Watch {
|
Watch {
|
|
@ -10,13 +10,6 @@ use std::{
|
||||||
};
|
};
|
||||||
use walkdir::{DirEntry, WalkDir};
|
use walkdir::{DirEntry, WalkDir};
|
||||||
|
|
||||||
pub(crate) struct Watcher {
|
|
||||||
watcher: RecommendedWatcher,
|
|
||||||
thread: thread::JoinHandle<()>,
|
|
||||||
bomb: DropBomb,
|
|
||||||
sender: Sender<io::Task>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum WatcherChange {
|
pub enum WatcherChange {
|
||||||
Create(PathBuf),
|
Create(PathBuf),
|
||||||
|
@ -61,6 +54,13 @@ fn handle_change_event(
|
||||||
|
|
||||||
const WATCHER_DELAY: Duration = Duration::from_millis(250);
|
const WATCHER_DELAY: Duration = Duration::from_millis(250);
|
||||||
|
|
||||||
|
pub(crate) struct Watcher {
|
||||||
|
watcher: RecommendedWatcher,
|
||||||
|
thread: thread::JoinHandle<()>,
|
||||||
|
bomb: DropBomb,
|
||||||
|
sender: Sender<io::Task>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Watcher {
|
impl Watcher {
|
||||||
pub(crate) fn start(
|
pub(crate) fn start(
|
||||||
output_sender: Sender<io::Task>,
|
output_sender: Sender<io::Task>,
|
|
@ -14,7 +14,6 @@
|
||||||
//! which are watched for changes. Typically, there will be a root for each
|
//! which are watched for changes. Typically, there will be a root for each
|
||||||
//! Cargo package.
|
//! Cargo package.
|
||||||
mod io;
|
mod io;
|
||||||
mod watcher;
|
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Reverse,
|
cmp::Reverse,
|
||||||
|
@ -32,7 +31,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use walkdir::DirEntry;
|
use walkdir::DirEntry;
|
||||||
|
|
||||||
pub use crate::io::TaskResult as VfsTask;
|
pub use crate::io::TaskResult as VfsTask;
|
||||||
pub use crate::watcher::WatcherChange;
|
use io::{Task, TaskResult, WatcherChange, WatcherChangeData, Worker};
|
||||||
|
|
||||||
/// `RootFilter` is a predicate that checks if a file can belong to a root. If
|
/// `RootFilter` is a predicate that checks if a file can belong to a root. If
|
||||||
/// several filters match a file (nested dirs), the most nested one wins.
|
/// several filters match a file (nested dirs), the most nested one wins.
|
||||||
|
@ -100,7 +99,7 @@ pub struct Vfs {
|
||||||
files: Arena<VfsFile, VfsFileData>,
|
files: Arena<VfsFile, VfsFileData>,
|
||||||
root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
|
root2files: FxHashMap<VfsRoot, FxHashSet<VfsFile>>,
|
||||||
pending_changes: Vec<VfsChange>,
|
pending_changes: Vec<VfsChange>,
|
||||||
worker: io::Worker,
|
worker: Worker,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Vfs {
|
impl fmt::Debug for Vfs {
|
||||||
|
@ -204,7 +203,7 @@ impl Vfs {
|
||||||
|
|
||||||
pub fn handle_task(&mut self, task: io::TaskResult) {
|
pub fn handle_task(&mut self, task: io::TaskResult) {
|
||||||
match task {
|
match task {
|
||||||
io::TaskResult::AddRoot(task) => {
|
TaskResult::AddRoot(task) => {
|
||||||
let mut files = Vec::new();
|
let mut files = Vec::new();
|
||||||
// While we were scanning the root in the backgound, a file might have
|
// While we were scanning the root in the backgound, a file might have
|
||||||
// been open in the editor, so we need to account for that.
|
// been open in the editor, so we need to account for that.
|
||||||
|
@ -229,38 +228,35 @@ impl Vfs {
|
||||||
};
|
};
|
||||||
self.pending_changes.push(change);
|
self.pending_changes.push(change);
|
||||||
}
|
}
|
||||||
io::TaskResult::HandleChange(change) => match &change {
|
TaskResult::HandleChange(change) => match &change {
|
||||||
watcher::WatcherChange::Create(path) if path.is_dir() => {
|
WatcherChange::Create(path) if path.is_dir() => {
|
||||||
if let Some((root, _path, _file)) = self.find_root(&path) {
|
if let Some((root, _path, _file)) = self.find_root(&path) {
|
||||||
let root_filter = self.roots[root].clone();
|
let root_filter = self.roots[root].clone();
|
||||||
let filter =
|
let filter =
|
||||||
move |entry: &DirEntry| root_filter.can_contain(entry.path()).is_some();
|
move |entry: &DirEntry| root_filter.can_contain(entry.path()).is_some();
|
||||||
self.worker
|
self.worker
|
||||||
.sender()
|
.sender()
|
||||||
.send(io::Task::Watch {
|
.send(Task::Watch {
|
||||||
dir: path.to_path_buf(),
|
dir: path.to_path_buf(),
|
||||||
filter: Box::new(filter),
|
filter: Box::new(filter),
|
||||||
})
|
})
|
||||||
.unwrap()
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
watcher::WatcherChange::Create(path)
|
WatcherChange::Create(path)
|
||||||
| watcher::WatcherChange::Remove(path)
|
| WatcherChange::Remove(path)
|
||||||
| watcher::WatcherChange::Write(path) => {
|
| WatcherChange::Write(path) => {
|
||||||
if self.should_handle_change(&path) {
|
if self.should_handle_change(&path) {
|
||||||
self.worker
|
self.worker.sender().send(Task::LoadChange(change)).unwrap()
|
||||||
.sender()
|
|
||||||
.send(io::Task::LoadChange(change))
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
watcher::WatcherChange::Rescan => {
|
WatcherChange::Rescan => {
|
||||||
// TODO we should reload all files
|
// TODO we should reload all files
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
io::TaskResult::LoadChange(change) => match change {
|
TaskResult::LoadChange(change) => match change {
|
||||||
io::WatcherChangeData::Create { path, text }
|
WatcherChangeData::Create { path, text }
|
||||||
| io::WatcherChangeData::Write { path, text } => {
|
| WatcherChangeData::Write { path, text } => {
|
||||||
if let Some((root, path, file)) = self.find_root(&path) {
|
if let Some((root, path, file)) = self.find_root(&path) {
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
self.do_change_file(file, text, false);
|
self.do_change_file(file, text, false);
|
||||||
|
@ -269,7 +265,7 @@ impl Vfs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io::WatcherChangeData::Remove { path } => {
|
WatcherChangeData::Remove { path } => {
|
||||||
if let Some((root, path, file)) = self.find_root(&path) {
|
if let Some((root, path, file)) = self.find_root(&path) {
|
||||||
if let Some(file) = file {
|
if let Some(file) = file {
|
||||||
self.do_remove_file(root, path, file, false);
|
self.do_remove_file(root, path, file, false);
|
||||||
|
@ -277,7 +273,7 @@ impl Vfs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
io::TaskResult::NoOp => {}
|
TaskResult::NoOp => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue