summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Nguyen <benjamin.van.nguyen@gmail.com>2023-11-29 15:49:41 -0800
committerBenjamin Nguyen <benjamin.van.nguyen@gmail.com>2023-11-29 15:49:41 -0800
commit867859b3ae2e3b6a7f68563477025bfd7bf2f1cf (patch)
treee5ed51cad794c3489baa47ba1e7ca11fe1aea83c
parent93d79b8a64d4fee8f8f404fb7b4f18cd27c25f44 (diff)
suppress size algorithm
-rw-r--r--src/file/mod.rs10
-rw-r--r--src/file/order.rs23
-rw-r--r--src/file/tree/mod.rs115
-rw-r--r--src/render/row/mod.rs4
-rw-r--r--src/user/args.rs2
5 files changed, 86 insertions, 68 deletions
diff --git a/src/file/mod.rs b/src/file/mod.rs
index 279b1f4..db1ba20 100644
--- a/src/file/mod.rs
+++ b/src/file/mod.rs
@@ -147,7 +147,10 @@ impl File {
}
pub fn display_path<'a>(&'a self, path_prefix: Option<&'a Path>) -> DisplayPath<'a> {
- DisplayPath { file: self, path_prefix }
+ DisplayPath {
+ file: self,
+ path_prefix,
+ }
}
#[cfg(unix)]
@@ -207,9 +210,10 @@ impl Display for DisplayPath<'_> {
let display = match self.path_prefix {
Some(prefix) => {
let path = self.file.path();
- path.strip_prefix(prefix).map_or_else(|_| path.display(), |p| p.display())
+ path.strip_prefix(prefix)
+ .map_or_else(|_| path.display(), |p| p.display())
},
- None => self.file.path().display()
+ None => self.file.path().display(),
};
let link_target = self.file.symlink_target().map(|p| p.canonicalize());
diff --git a/src/file/order.rs b/src/file/order.rs
index de22546..b3cd8a1 100644
--- a/src/file/order.rs
+++ b/src/file/order.rs
@@ -8,15 +8,11 @@ pub type FileComparator = dyn Fn(&File, &File) -> Ordering;
/// Yields function pointer to the appropriate `File` comparator.
pub fn comparator(sort: Sort, dir_order: DirOrder) -> Option<Box<FileComparator>> {
match dir_order {
- DirOrder::First if matches!(sort, Sort::None) => Some(Box::new(move |a, b| {
- dir_first_comparator(a, b)
- })),
+ DirOrder::First if matches!(sort, Sort::None) => Some(Box::new(dir_first_comparator)),
DirOrder::First => Some(Box::new(move |a, b| {
dir_first_comparator_with_fallback(a, b, base_comparator(sort))
})),
- DirOrder::Last if matches!(sort, Sort::None) => Some(Box::new(move |a, b| {
- dir_last_comparator(a, b)
- })),
+ DirOrder::Last if matches!(sort, Sort::None) => Some(Box::new(dir_last_comparator)),
DirOrder::Last => Some(Box::new(move |a, b| {
dir_last_comparator_with_fallback(a, b, base_comparator(sort))
})),
@@ -43,7 +39,7 @@ fn dir_first_comparator(a: &File, b: &File) -> Ordering {
match (a.is_dir(), b.is_dir()) {
(true, false) => Ordering::Greater,
(false, true) => Ordering::Less,
- _ => Ordering::Equal
+ _ => Ordering::Equal,
}
}
@@ -61,14 +57,11 @@ fn dir_last_comparator_with_fallback(
}
/// Orders directories last relative to all other file-types.
-fn dir_last_comparator(
- a: &File,
- b: &File,
-) -> Ordering {
+fn dir_last_comparator(a: &File, b: &File) -> Ordering {
match (a.is_dir(), b.is_dir()) {
(true, false) => Ordering::Less,
(false, true) => Ordering::Greater,
- _ => Ordering::Equal
+ _ => Ordering::Equal,
}
}
@@ -90,9 +83,9 @@ fn base_comparator(sort_type: Sort) -> Box<FileComparator> {
}
mod time_stamping {
- pub(self) use super::File;
- pub(self) use core::cmp::Ordering;
- pub(self) use std::time::SystemTime;
+ use super::File;
+ use core::cmp::Ordering;
+ use std::time::SystemTime;
pub mod accessed {
use super::*;
diff --git a/src/file/tree/mod.rs b/src/file/tree/mod.rs
index aaf2912..c805a27 100644
--- a/src/file/tree/mod.rs
+++ b/src/file/tree/mod.rs
@@ -1,8 +1,11 @@
-use super::order::{self, FileComparator};
+use super::order;
use crate::{
error::prelude::*,
file::File,
- user::{args::{Layout, SortType, Sort}, column, Context},
+ user::{
+ args::{Layout, Sort, SortType},
+ column, Context,
+ },
};
use ahash::{HashMap, HashSet};
use indextree::{Arena, NodeId};
@@ -128,9 +131,11 @@ impl Tree {
comparator(node_a, node_b)
});
- all_dirents.into_iter().for_each(|n| root_id.append(n, &mut arena));
- }
- _ => {
+ all_dirents
+ .into_iter()
+ .for_each(|n| root_id.append(n, &mut arena));
+ },
+ _ => {
for (dir_id, dirsize) in dirsize_map.into_iter() {
let dir = arena[dir_id].get_mut();
*dir.size_mut() += dirsize;
@@ -178,51 +183,72 @@ impl Tree {
root_id,
} = Self::load(ctx)?;
- let mut dir_stack = vec![root_id];
-
- 'outer: while let Some(node_id) = dir_stack.last() {
- let current_dir = *node_id;
-
- let current_node_path = arena[current_dir].get().path();
-
- let Some(dirents) = branches.get_mut(current_node_path) else {
- dir_stack.pop();
- continue;
+ #[cfg(unix)]
+ macro_rules! update_metadata {
+ ($dirent_id:expr) => {
+ let dirent = arena[$dirent_id].get();
+ if let Ok(inode) = dirent.inode() {
+ column_metadata.update_inode_attr_widths(&inode);
+ }
};
+ }
- while let Some(dirent_node_id) = dirents.pop() {
- current_dir.append(dirent_node_id, &mut arena);
+ match ctx.sort_type {
+ SortType::Flat if matches!(ctx.layout, Layout::Flat) => {
+ let mut all_dirents = branches
+ .values()
+ .flatten()
+ .filter_map(|n| (*n != root_id).then_some(*n))
+ .collect::<Vec<_>>();
- let dirent_node = arena[dirent_node_id].get();
+ if let Some(comparator) = order::comparator(Sort::None, ctx.dir_order) {
+ all_dirents.sort_by(|id_a, id_b| {
+ let node_a = arena[*id_a].get();
+ let node_b = arena[*id_b].get();
+ comparator(node_a, node_b)
+ });
+ }
- #[cfg(unix)]
- match dirent_node.inode() {
- Ok(value) => {
- column_metadata.update_inode_attr_widths(&value);
- value
- },
- Err(err) => {
- log::warn!(
- "Failed to query inode of {}: {err}",
- dirent_node.path().display(),
- );
- continue;
- },
- };
+ for dirent_id in all_dirents {
+ root_id.append(dirent_id, &mut arena);
- if dirent_node.file_type().is_some_and(|f| f.is_dir()) {
- dir_stack.push(dirent_node_id);
- continue 'outer;
+ #[cfg(unix)]
+ update_metadata!(dirent_id);
}
- }
+ },
+ _ => {
+ let dirs = arena
+ .iter()
+ .filter_map(|node| {
+ if node.get().is_dir() {
+ arena
+ .get_node_id(node)
+ .map(|n| (node.get().path().to_path_buf(), n))
+ } else {
+ None
+ }
+ })
+ .collect::<Vec<_>>();
- dir_stack.pop();
- }
+ dirs.into_iter().for_each(|(path, dir)| {
+ if let Some(mut dirents) = branches.remove(&path) {
+ if let Some(comparator) = order::comparator(Sort::None, ctx.dir_order) {
+ dirents.sort_by(|id_a, id_b| {
+ let node_a = arena[*id_a].get();
+ let node_b = arena[*id_b].get();
+ comparator(node_a, node_b)
+ });
+ }
- if !matches!(ctx.sort, Sort::Size | Sort::Rsize) {
- if let Some(comparator) = order::comparator(ctx.sort, ctx.dir_order) {
- Self::tree_sort(root_id, &mut arena, comparator);
- }
+ for dirent_id in dirents {
+ dir.append(dirent_id, &mut arena);
+
+ #[cfg(unix)]
+ update_metadata!(dirent_id);
+ }
+ }
+ });
+ },
}
let tree = Self { root_id, arena };
@@ -291,11 +317,6 @@ impl Tree {
pub fn arena(&self) -> &Arena<File> {
&self.arena
}
-
- /// Sort [`File`]s in the `arena` with the provided `comparator`.
- pub fn tree_sort(root_id: NodeId, arena: &mut Arena<File>, comparator: Box<FileComparator>) {
- todo!()
- }
}
impl Deref for Tree {
diff --git a/src/render/row/mod.rs b/src/render/row/mod.rs
index f392340..f59fa91 100644
--- a/src/render/row/mod.rs
+++ b/src/render/row/mod.rs
@@ -77,7 +77,7 @@ pub fn formatter<'a>(buf: &'a mut String, ctx: &'a Context) -> Result<RowFormatt
let long_format = long::Format::new(file, ctx);
writeln!(buf, "{long_format} {prefix}{name}")
})),
- }
+ },
}
}
@@ -117,6 +117,6 @@ pub fn formatter<'a>(buf: &'a mut String, ctx: &'a Context) -> Result<RowFormatt
writeln!(buf, "{size:>max_size_width$} {prefix}{name}")
}))
}
- }
+ },
}
}
diff --git a/src/user/args.rs b/src/user/args.rs
index 4484be4..06990c0 100644
--- a/src/user/args.rs
+++ b/src/user/args.rs
@@ -135,7 +135,7 @@ pub enum SortType {
#[default]
Tree,
/// Sort directory entries relative to all directory entries
- Flat
+ Flat,
}
/// How directories should be ordered relative to regular files.