Files · Find and look: preview, recent files, search, duplicates and archives

FilePreview shows a file large: its picture in the host's shape, the first
lines of its text, or its kind's icon, over its name, kind, size and
change; the gallery opens it on Space as a quick look. RecentFiles lists
files newest first under a header a day, a list a day. FileSearch sits
over a field the host owns and lists what the host found with its folder.
DuplicateFinder marks copies to remove and keeps the last of each group,
its mark shut, with the bytes the marks free beside Remove. ArchiveViewer
draws an archive's entries as a tree with sizes and savings, from paths
gathered by the folder builder the file tree now shares. A checkbox's
label wraps inside its box instead of running past it. Favorites and the
hex viewer point to documents and debug.
This commit is contained in:
ZacharyZhang-NY committed 2026-09-26 20:42:06 -04:00
1 parent 4717aad596
commit d76a489934
17 files changed
+1507 -22

No files matched your search

+20 -12
View File
@@ -59,9 +59,25 @@ impl GitStatus {
/// A folder of the tree being built: its folders and its files, each by name.
#[derive(Default)]
struct Folder {
folders: BTreeMap<String, Folder>,
files: Vec<String>,
pub(crate) struct Folder {
pub folders: BTreeMap<String, Folder>,
pub files: Vec<String>,
}
impl Folder {
/// Paths with `/` between folders, gathered into the folders that hold them.
pub(crate) fn of<'a>(paths: impl IntoIterator<Item = &'a str>) -> Self {
let mut root = Folder::default();
for path in paths {
let mut parts: Vec<&str> = path.split('/').collect();
let file = parts.pop().expect("a path has a name").to_string();
let folder = parts.iter().fold(&mut root, |folder, part| {
folder.folders.entry(part.to_string()).or_default()
});
folder.files.push(file);
}
root
}
}
/// Whether `name` matches `query`, ignoring case; an empty query matches all.
@@ -75,15 +91,7 @@ fn nodes(
status: &[(SharedString, GitStatus)],
query: &str,
) -> (Vec<TreeNode>, Vec<SharedString>) {
let mut root = Folder::default();
for path in paths {
let mut parts: Vec<&str> = path.split('/').collect();
let file = parts.pop().expect("a path has a name").to_string();
let folder = parts.iter().fold(&mut root, |folder, part| {
folder.folders.entry(part.to_string()).or_default()
});
folder.files.push(file);
}
let root = Folder::of(paths.iter().map(|path| path.as_ref()));
let state = |path: &str| {
status
.iter()
+1
View File
@@ -13,6 +13,7 @@ mod tree;
pub use directory::{DirEntry, DirectoryListing};
pub(crate) use directory::{OnClimb, listed, path_bar};
pub(crate) use files::Folder;
pub use files::{FileTree, GitStatus};
pub use grouped::GroupedList;
pub use item::{List, ListItem};