From cdb20c392d4c534f602df51d0ee509b61f892a4d Mon Sep 17 00:00:00 2001 From: Yifan Song Date: Sat, 12 Aug 2023 22:03:37 +0800 Subject: [PATCH] Use a cool lambda to make sort in one pass and change pos in doc --- config/docs/yazi.md | 10 +++--- config/preset/yazi.toml | 2 +- core/src/files/files.rs | 79 +++++++++++++++++++++++++++-------------- 3 files changed, 58 insertions(+), 33 deletions(-) diff --git a/config/docs/yazi.md b/config/docs/yazi.md index 3a27173b..550a7a3e 100644 --- a/config/docs/yazi.md +++ b/config/docs/yazi.md @@ -9,16 +9,16 @@ - `"modified"`: Sort by last modified time - `"size"`: Sort by file size -- sort_reverse: Display files in reverse order - - - `true`: Reverse order - - `false`: Normal order - - sort_dir_first: Display files in reverse order - `true`: Directory at first - `false`: Sort According to `sort_by` +- sort_reverse: Display files in reverse order + + - `true`: Reverse order + - `false`: Normal order + - show_hidden: Show hidden files - `true`: Show diff --git a/config/preset/yazi.toml b/config/preset/yazi.toml index 18e4c18e..0b036d35 100644 --- a/config/preset/yazi.toml +++ b/config/preset/yazi.toml @@ -1,8 +1,8 @@ [manager] sort_by = "modified" +sort_dir_first = true sort_reverse = true show_hidden = false -sort_dir_first = true [preview] tab_size = 2 diff --git a/core/src/files/files.rs b/core/src/files/files.rs index 5ce3dca0..8058101c 100644 --- a/core/src/files/files.rs +++ b/core/src/files/files.rs @@ -116,38 +116,63 @@ impl Files { return false; } + fn cmp_dir(a: &File, b: &File, dir_first: bool) -> Option { + if !dir_first { + return None; + } + if a.meta.is_dir() && !b.meta.is_dir() { + return Some(std::cmp::Ordering::Less); + } else if !a.meta.is_dir() && b.meta.is_dir() { + return Some(std::cmp::Ordering::Greater); + } + None + } + + fn cmp( + a: &File, + b: &File, + dir_first: bool, + reverse: bool, + inner_cmp: T, + ) -> std::cmp::Ordering + where + T: Fn(&File, &File) -> std::cmp::Ordering, + { + let res = match cmp_dir(a, b, dir_first) { + Some(expr) => expr, + None => inner_cmp(a, b), + }; + if reverse { res.reverse() } else { res } + } + + let dir_first = self.sort.dir_first; + let reverse = self.sort.reverse; + match self.sort.by { - SortBy::Alphabetical => self.items.sort_by(|_, a, _, b| (&a.path).cmp(&b.path)), + SortBy::Alphabetical => self.items.sort_by(|_, a, _, b| { + cmp(a, b, dir_first, reverse, |a: &File, b: &File| a.path.cmp(&b.path)) + }), SortBy::Created => self.items.sort_by(|_, a, _, b| { - if let (Ok(a), Ok(b)) = (a.meta.created(), b.meta.created()) { - return (&a).cmp(&b); - } - std::cmp::Ordering::Equal + cmp(a, b, dir_first, reverse, |a: &File, b: &File| { + if let (Ok(a), Ok(b)) = (a.meta.created(), b.meta.created()) { + return (&a).cmp(&b); + } + std::cmp::Ordering::Equal + }) }), SortBy::Modified => self.items.sort_by(|_, a, _, b| { - if let (Ok(a), Ok(b)) = (a.meta.modified(), b.meta.modified()) { - return (&a).cmp(&b); - } - std::cmp::Ordering::Equal + cmp(a, b, dir_first, reverse, |a: &File, b: &File| { + if let (Ok(a), Ok(b)) = (a.meta.modified(), b.meta.modified()) { + return (&a).cmp(&b); + } + std::cmp::Ordering::Equal + }) + }), + SortBy::Size => self.items.sort_by(|_, a, _, b| { + cmp(a, b, dir_first, reverse, |a: &File, b: &File| { + (a.length.unwrap_or(0)).cmp(&b.length.unwrap_or(0)) + }) }), - SortBy::Size => { - self.items.sort_by(|_, a, _, b| (a.length.unwrap_or(0)).cmp(&b.length.unwrap_or(0))) - } - } - - if self.sort.dir_first { - self.items.sort_by(|_, a, _, b| { - if a.meta.is_dir() && !b.meta.is_dir() { - return std::cmp::Ordering::Less; - } else if !a.meta.is_dir() && b.meta.is_dir() { - return std::cmp::Ordering::Greater; - } - std::cmp::Ordering::Equal - }); - } - - if self.sort.reverse { - self.items.reverse(); } true