diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-09-11 12:37:04 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-09-11 12:37:04 +0100 |
commit | 4f1167d8ddac9d392f034341e6bc032b51014918 (patch) | |
tree | f26520ae48d4670aaefd2d62f9de37af30ef5bac /crates/vfs/src | |
parent | eb7136f76d3535fde25dc6f49e3035312f7cc84c (diff) | |
parent | ca698a0b8c78e5ba7738fc0f0f6f77718e70a83e (diff) |
Merge #5969
5969: Propose module name completion options r=jonas-schievink a=SomeoneToIgnore
<img width="539" alt="image" src="https://user-images.githubusercontent.com/2690773/92663009-cb0aec00-f308-11ea-9ef5-1faa91518031.png">
Currently traverses the whole file set every time we try to complete the module, as discussed in https://rust-lang.zulipchat.com/#narrow/stream/185405-t-compiler.2Fwg-rls-2.2E0/topic/mod.3C.7C.3E.20completion
Co-authored-by: Kirill Bulatov <[email protected]>
Diffstat (limited to 'crates/vfs/src')
-rw-r--r-- | crates/vfs/src/file_set.rs | 13 | ||||
-rw-r--r-- | crates/vfs/src/vfs_path.rs | 74 |
2 files changed, 85 insertions, 2 deletions
diff --git a/crates/vfs/src/file_set.rs b/crates/vfs/src/file_set.rs index e9196fcd2..4aa2d6526 100644 --- a/crates/vfs/src/file_set.rs +++ b/crates/vfs/src/file_set.rs | |||
@@ -23,13 +23,22 @@ impl FileSet { | |||
23 | let mut base = self.paths[&anchor].clone(); | 23 | let mut base = self.paths[&anchor].clone(); |
24 | base.pop(); | 24 | base.pop(); |
25 | let path = base.join(path)?; | 25 | let path = base.join(path)?; |
26 | let res = self.files.get(&path).copied(); | 26 | self.files.get(&path).copied() |
27 | res | 27 | } |
28 | |||
29 | pub fn file_for_path(&self, path: &VfsPath) -> Option<&FileId> { | ||
30 | self.files.get(path) | ||
28 | } | 31 | } |
32 | |||
33 | pub fn path_for_file(&self, file: &FileId) -> Option<&VfsPath> { | ||
34 | self.paths.get(file) | ||
35 | } | ||
36 | |||
29 | pub fn insert(&mut self, file_id: FileId, path: VfsPath) { | 37 | pub fn insert(&mut self, file_id: FileId, path: VfsPath) { |
30 | self.files.insert(path.clone(), file_id); | 38 | self.files.insert(path.clone(), file_id); |
31 | self.paths.insert(file_id, path); | 39 | self.paths.insert(file_id, path); |
32 | } | 40 | } |
41 | |||
33 | pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { | 42 | pub fn iter(&self) -> impl Iterator<Item = FileId> + '_ { |
34 | self.paths.keys().copied() | 43 | self.paths.keys().copied() |
35 | } | 44 | } |
diff --git a/crates/vfs/src/vfs_path.rs b/crates/vfs/src/vfs_path.rs index 944a702df..022a0be1e 100644 --- a/crates/vfs/src/vfs_path.rs +++ b/crates/vfs/src/vfs_path.rs | |||
@@ -48,6 +48,24 @@ impl VfsPath { | |||
48 | (VfsPathRepr::VirtualPath(_), _) => false, | 48 | (VfsPathRepr::VirtualPath(_), _) => false, |
49 | } | 49 | } |
50 | } | 50 | } |
51 | pub fn parent(&self) -> Option<VfsPath> { | ||
52 | let mut parent = self.clone(); | ||
53 | if parent.pop() { | ||
54 | Some(parent) | ||
55 | } else { | ||
56 | None | ||
57 | } | ||
58 | } | ||
59 | |||
60 | pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { | ||
61 | match &self.0 { | ||
62 | VfsPathRepr::PathBuf(p) => Some(( | ||
63 | p.file_stem()?.to_str()?, | ||
64 | p.extension().and_then(|extension| extension.to_str()), | ||
65 | )), | ||
66 | VfsPathRepr::VirtualPath(p) => p.name_and_extension(), | ||
67 | } | ||
68 | } | ||
51 | 69 | ||
52 | // Don't make this `pub` | 70 | // Don't make this `pub` |
53 | pub(crate) fn encode(&self, buf: &mut Vec<u8>) { | 71 | pub(crate) fn encode(&self, buf: &mut Vec<u8>) { |
@@ -268,4 +286,60 @@ impl VirtualPath { | |||
268 | res.0 = format!("{}/{}", res.0, path); | 286 | res.0 = format!("{}/{}", res.0, path); |
269 | Some(res) | 287 | Some(res) |
270 | } | 288 | } |
289 | |||
290 | pub fn name_and_extension(&self) -> Option<(&str, Option<&str>)> { | ||
291 | let file_path = if self.0.ends_with('/') { &self.0[..&self.0.len() - 1] } else { &self.0 }; | ||
292 | let file_name = match file_path.rfind('/') { | ||
293 | Some(position) => &file_path[position + 1..], | ||
294 | None => file_path, | ||
295 | }; | ||
296 | |||
297 | if file_name.is_empty() { | ||
298 | None | ||
299 | } else { | ||
300 | let mut file_stem_and_extension = file_name.rsplitn(2, '.'); | ||
301 | let extension = file_stem_and_extension.next(); | ||
302 | let file_stem = file_stem_and_extension.next(); | ||
303 | |||
304 | match (file_stem, extension) { | ||
305 | (None, None) => None, | ||
306 | (None, Some(_)) | (Some(""), Some(_)) => Some((file_name, None)), | ||
307 | (Some(file_stem), extension) => Some((file_stem, extension)), | ||
308 | } | ||
309 | } | ||
310 | } | ||
311 | } | ||
312 | |||
313 | #[cfg(test)] | ||
314 | mod tests { | ||
315 | use super::*; | ||
316 | |||
317 | #[test] | ||
318 | fn virtual_path_extensions() { | ||
319 | assert_eq!(VirtualPath("/".to_string()).name_and_extension(), None); | ||
320 | assert_eq!( | ||
321 | VirtualPath("/directory".to_string()).name_and_extension(), | ||
322 | Some(("directory", None)) | ||
323 | ); | ||
324 | assert_eq!( | ||
325 | VirtualPath("/directory/".to_string()).name_and_extension(), | ||
326 | Some(("directory", None)) | ||
327 | ); | ||
328 | assert_eq!( | ||
329 | VirtualPath("/directory/file".to_string()).name_and_extension(), | ||
330 | Some(("file", None)) | ||
331 | ); | ||
332 | assert_eq!( | ||
333 | VirtualPath("/directory/.file".to_string()).name_and_extension(), | ||
334 | Some((".file", None)) | ||
335 | ); | ||
336 | assert_eq!( | ||
337 | VirtualPath("/directory/.file.rs".to_string()).name_and_extension(), | ||
338 | Some((".file", Some("rs"))) | ||
339 | ); | ||
340 | assert_eq!( | ||
341 | VirtualPath("/directory/file.rs".to_string()).name_and_extension(), | ||
342 | Some(("file", Some("rs"))) | ||
343 | ); | ||
344 | } | ||
271 | } | 345 | } |