| 29 | |
| 30 | impl FileIndex { |
| 31 | pub fn refresh(&mut self, root: &Path, max_depth: usize) { |
| 32 | let depth = max_depth.max(1); |
| 33 | let root_buf = root.to_path_buf(); |
| 34 | let now = Instant::now(); |
| 35 | if self.root.as_ref() == Some(&root_buf) |
| 36 | && self.max_depth == depth |
| 37 | && self |
| 38 | .last_refresh |
| 39 | .is_some_and(|last| now.duration_since(last) < REFRESH_INTERVAL) |
| 40 | { |
| 41 | return; |
| 42 | } |
| 43 | |
| 44 | let mut entries = Vec::new(); |
| 45 | for entry in WalkDir::new(root) |
| 46 | .follow_links(false) |
| 47 | .max_depth(depth) |
| 48 | .into_iter() |
| 49 | .filter_entry(should_descend) |
| 50 | .filter_map(Result::ok) |
| 51 | .filter(|entry| entry.file_type().is_file()) |
| 52 | { |
| 53 | if let Ok(relative) = entry.path().strip_prefix(root) { |
| 54 | let value = relative.to_string_lossy().replace('\\', "/"); |
| 55 | if !value.is_empty() { |
| 56 | entries.push(value); |
| 57 | } |
| 58 | } |
| 59 | } |
| 60 | |
| 61 | entries.sort(); |
| 62 | entries.dedup(); |
| 63 | self.entries = entries; |
| 64 | self.root = Some(root_buf); |
| 65 | self.max_depth = depth; |
| 66 | self.last_refresh = Some(now); |
| 67 | } |
| 68 | |
| 69 | pub fn search(&self, query: &str, limit: usize) -> Vec<(String, u32)> { |
| 70 | if limit == 0 || self.entries.is_empty() { |