Use a cool lambda to make sort in one pass and change pos in doc

This commit is contained in:
Yifan Song 2023-08-12 22:03:37 +08:00
parent 016452514b
commit cdb20c392d
3 changed files with 58 additions and 33 deletions

View file

@ -9,16 +9,16 @@
- `"modified"`: Sort by last modified time - `"modified"`: Sort by last modified time
- `"size"`: Sort by file size - `"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 - sort_dir_first: Display files in reverse order
- `true`: Directory at first - `true`: Directory at first
- `false`: Sort According to `sort_by` - `false`: Sort According to `sort_by`
- sort_reverse: Display files in reverse order
- `true`: Reverse order
- `false`: Normal order
- show_hidden: Show hidden files - show_hidden: Show hidden files
- `true`: Show - `true`: Show

View file

@ -1,8 +1,8 @@
[manager] [manager]
sort_by = "modified" sort_by = "modified"
sort_dir_first = true
sort_reverse = true sort_reverse = true
show_hidden = false show_hidden = false
sort_dir_first = true
[preview] [preview]
tab_size = 2 tab_size = 2

View file

@ -116,38 +116,63 @@ impl Files {
return false; return false;
} }
fn cmp_dir(a: &File, b: &File, dir_first: bool) -> Option<std::cmp::Ordering> {
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<T>(
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 { 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| { SortBy::Created => self.items.sort_by(|_, a, _, b| {
if let (Ok(a), Ok(b)) = (a.meta.created(), b.meta.created()) { cmp(a, b, dir_first, reverse, |a: &File, b: &File| {
return (&a).cmp(&b); if let (Ok(a), Ok(b)) = (a.meta.created(), b.meta.created()) {
} return (&a).cmp(&b);
std::cmp::Ordering::Equal }
std::cmp::Ordering::Equal
})
}), }),
SortBy::Modified => self.items.sort_by(|_, a, _, b| { SortBy::Modified => self.items.sort_by(|_, a, _, b| {
if let (Ok(a), Ok(b)) = (a.meta.modified(), b.meta.modified()) { cmp(a, b, dir_first, reverse, |a: &File, b: &File| {
return (&a).cmp(&b); if let (Ok(a), Ok(b)) = (a.meta.modified(), b.meta.modified()) {
} return (&a).cmp(&b);
std::cmp::Ordering::Equal }
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 true