diff options
Diffstat (limited to 'crates/ra_vfs')
| -rw-r--r-- | crates/ra_vfs/src/io.rs | 7 | ||||
| -rw-r--r-- | crates/ra_vfs/src/lib.rs | 53 |
2 files changed, 54 insertions, 6 deletions
diff --git a/crates/ra_vfs/src/io.rs b/crates/ra_vfs/src/io.rs index 178c9beff..be400bae9 100644 --- a/crates/ra_vfs/src/io.rs +++ b/crates/ra_vfs/src/io.rs | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | use std::{ | 1 | use std::{ |
| 2 | fmt, | ||
| 2 | fs, | 3 | fs, |
| 3 | path::{Path, PathBuf}, | 4 | path::{Path, PathBuf}, |
| 4 | }; | 5 | }; |
| @@ -20,6 +21,12 @@ pub struct TaskResult { | |||
| 20 | pub(crate) files: Vec<(RelativePathBuf, String)>, | 21 | pub(crate) files: Vec<(RelativePathBuf, String)>, |
| 21 | } | 22 | } |
| 22 | 23 | ||
| 24 | impl fmt::Debug for TaskResult { | ||
| 25 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| 26 | f.write_str("TaskResult { ... }") | ||
| 27 | } | ||
| 28 | } | ||
| 29 | |||
| 23 | pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>; | 30 | pub(crate) type Worker = thread_worker::Worker<Task, TaskResult>; |
| 24 | 31 | ||
| 25 | pub(crate) fn start() -> (Worker, WorkerHandle) { | 32 | pub(crate) fn start() -> (Worker, WorkerHandle) { |
diff --git a/crates/ra_vfs/src/lib.rs b/crates/ra_vfs/src/lib.rs index 6c1af5ef9..dc980c3d2 100644 --- a/crates/ra_vfs/src/lib.rs +++ b/crates/ra_vfs/src/lib.rs | |||
| @@ -15,6 +15,7 @@ mod arena; | |||
| 15 | mod io; | 15 | mod io; |
| 16 | 16 | ||
| 17 | use std::{ | 17 | use std::{ |
| 18 | fmt, | ||
| 18 | mem, | 19 | mem, |
| 19 | thread, | 20 | thread, |
| 20 | cmp::Reverse, | 21 | cmp::Reverse, |
| @@ -34,6 +35,8 @@ use crate::{ | |||
| 34 | arena::{ArenaId, Arena}, | 35 | arena::{ArenaId, Arena}, |
| 35 | }; | 36 | }; |
| 36 | 37 | ||
| 38 | pub use crate::io::TaskResult as VfsTask; | ||
| 39 | |||
| 37 | /// `RootFilter` is a predicate that checks if a file can belong to a root. If | 40 | /// `RootFilter` is a predicate that checks if a file can belong to a root. If |
| 38 | /// several filters match a file (nested dirs), the most nested one wins. | 41 | /// several filters match a file (nested dirs), the most nested one wins. |
| 39 | struct RootFilter { | 42 | struct RootFilter { |
| @@ -68,7 +71,7 @@ fn has_rs_extension(p: &Path) -> bool { | |||
| 68 | } | 71 | } |
| 69 | 72 | ||
| 70 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 73 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
| 71 | pub struct VfsRoot(u32); | 74 | pub struct VfsRoot(pub u32); |
| 72 | 75 | ||
| 73 | impl ArenaId for VfsRoot { | 76 | impl ArenaId for VfsRoot { |
| 74 | fn from_u32(idx: u32) -> VfsRoot { | 77 | fn from_u32(idx: u32) -> VfsRoot { |
| @@ -80,7 +83,7 @@ impl ArenaId for VfsRoot { | |||
| 80 | } | 83 | } |
| 81 | 84 | ||
| 82 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 85 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
| 83 | pub struct VfsFile(u32); | 86 | pub struct VfsFile(pub u32); |
| 84 | 87 | ||
| 85 | impl ArenaId for VfsFile { | 88 | impl ArenaId for VfsFile { |
| 86 | fn from_u32(idx: u32) -> VfsFile { | 89 | fn from_u32(idx: u32) -> VfsFile { |
| @@ -106,8 +109,14 @@ pub struct Vfs { | |||
| 106 | worker_handle: WorkerHandle, | 109 | worker_handle: WorkerHandle, |
| 107 | } | 110 | } |
| 108 | 111 | ||
| 112 | impl fmt::Debug for Vfs { | ||
| 113 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { | ||
| 114 | f.write_str("Vfs { ... }") | ||
| 115 | } | ||
| 116 | } | ||
| 117 | |||
| 109 | impl Vfs { | 118 | impl Vfs { |
| 110 | pub fn new(mut roots: Vec<PathBuf>) -> Vfs { | 119 | pub fn new(mut roots: Vec<PathBuf>) -> (Vfs, Vec<VfsRoot>) { |
| 111 | let (worker, worker_handle) = io::start(); | 120 | let (worker, worker_handle) = io::start(); |
| 112 | 121 | ||
| 113 | let mut res = Vfs { | 122 | let mut res = Vfs { |
| @@ -142,7 +151,32 @@ impl Vfs { | |||
| 142 | }; | 151 | }; |
| 143 | res.worker.inp.send(task); | 152 | res.worker.inp.send(task); |
| 144 | } | 153 | } |
| 145 | res | 154 | let roots = res.roots.iter().map(|(id, _)| id).collect(); |
| 155 | (res, roots) | ||
| 156 | } | ||
| 157 | |||
| 158 | pub fn path2file(&self, path: &Path) -> Option<VfsFile> { | ||
| 159 | if let Some((_root, _path, Some(file))) = self.find_root(path) { | ||
| 160 | return Some(file); | ||
| 161 | } | ||
| 162 | None | ||
| 163 | } | ||
| 164 | |||
| 165 | pub fn file2path(&self, file: VfsFile) -> PathBuf { | ||
| 166 | let rel_path = &self.files[file].path; | ||
| 167 | let root_path = &self.roots[self.files[file].root].root; | ||
| 168 | rel_path.to_path(root_path) | ||
| 169 | } | ||
| 170 | |||
| 171 | pub fn file_for_path(&self, path: &Path) -> Option<VfsFile> { | ||
| 172 | if let Some((_root, _path, Some(file))) = self.find_root(path) { | ||
| 173 | return Some(file); | ||
| 174 | } | ||
| 175 | None | ||
| 176 | } | ||
| 177 | |||
| 178 | pub fn load(&mut self, path: &Path) -> Option<VfsFile> { | ||
| 179 | None | ||
| 146 | } | 180 | } |
| 147 | 181 | ||
| 148 | pub fn task_receiver(&self) -> &Receiver<io::TaskResult> { | 182 | pub fn task_receiver(&self) -> &Receiver<io::TaskResult> { |
| @@ -163,14 +197,17 @@ impl Vfs { | |||
| 163 | self.pending_changes.push(change); | 197 | self.pending_changes.push(change); |
| 164 | } | 198 | } |
| 165 | 199 | ||
| 166 | pub fn add_file_overlay(&mut self, path: &Path, text: String) { | 200 | pub fn add_file_overlay(&mut self, path: &Path, text: String) -> Option<VfsFile> { |
| 201 | let mut res = None; | ||
| 167 | if let Some((root, path, file)) = self.find_root(path) { | 202 | if let Some((root, path, file)) = self.find_root(path) { |
| 168 | let text = Arc::new(text); | 203 | let text = Arc::new(text); |
| 169 | let change = if let Some(file) = file { | 204 | let change = if let Some(file) = file { |
| 205 | res = Some(file); | ||
| 170 | self.change_file(file, Arc::clone(&text)); | 206 | self.change_file(file, Arc::clone(&text)); |
| 171 | VfsChange::ChangeFile { file, text } | 207 | VfsChange::ChangeFile { file, text } |
| 172 | } else { | 208 | } else { |
| 173 | let file = self.add_file(root, path.clone(), Arc::clone(&text)); | 209 | let file = self.add_file(root, path.clone(), Arc::clone(&text)); |
| 210 | res = Some(file); | ||
| 174 | VfsChange::AddFile { | 211 | VfsChange::AddFile { |
| 175 | file, | 212 | file, |
| 176 | text, | 213 | text, |
| @@ -180,6 +217,7 @@ impl Vfs { | |||
| 180 | }; | 217 | }; |
| 181 | self.pending_changes.push(change); | 218 | self.pending_changes.push(change); |
| 182 | } | 219 | } |
| 220 | res | ||
| 183 | } | 221 | } |
| 184 | 222 | ||
| 185 | pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { | 223 | pub fn change_file_overlay(&mut self, path: &Path, new_text: String) { |
| @@ -192,9 +230,11 @@ impl Vfs { | |||
| 192 | } | 230 | } |
| 193 | } | 231 | } |
| 194 | 232 | ||
| 195 | pub fn remove_file_overlay(&mut self, path: &Path) { | 233 | pub fn remove_file_overlay(&mut self, path: &Path) -> Option<VfsFile> { |
| 234 | let mut res = None; | ||
| 196 | if let Some((root, path, file)) = self.find_root(path) { | 235 | if let Some((root, path, file)) = self.find_root(path) { |
| 197 | let file = file.expect("can't remove a file which wasn't added"); | 236 | let file = file.expect("can't remove a file which wasn't added"); |
| 237 | res = Some(file); | ||
| 198 | let full_path = path.to_path(&self.roots[root].root); | 238 | let full_path = path.to_path(&self.roots[root].root); |
| 199 | let change = if let Ok(text) = fs::read_to_string(&full_path) { | 239 | let change = if let Ok(text) = fs::read_to_string(&full_path) { |
| 200 | let text = Arc::new(text); | 240 | let text = Arc::new(text); |
| @@ -206,6 +246,7 @@ impl Vfs { | |||
| 206 | }; | 246 | }; |
| 207 | self.pending_changes.push(change); | 247 | self.pending_changes.push(change); |
| 208 | } | 248 | } |
| 249 | res | ||
| 209 | } | 250 | } |
| 210 | 251 | ||
| 211 | pub fn commit_changes(&mut self) -> Vec<VfsChange> { | 252 | pub fn commit_changes(&mut self) -> Vec<VfsChange> { |
