summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/config/mimetype.rs10
-rw-r--r--src/fs/dirlist.rs7
-rw-r--r--src/fs/entry.rs48
-rw-r--r--src/util/sort.rs104
4 files changed, 52 insertions, 117 deletions
diff --git a/src/config/mimetype.rs b/src/config/mimetype.rs
index f8b163f..0520d9e 100644
--- a/src/config/mimetype.rs
+++ b/src/config/mimetype.rs
@@ -33,12 +33,12 @@ impl JoshutoMimetypeEntry {
}
}
- pub fn arg<S: std::convert::Into<String>>(mut self, arg: S) -> Self {
+ pub fn arg<S: std::convert::Into<String>>(&mut self, arg: S) -> &mut Self {
self._args.push(arg.into());
self
}
- pub fn args<I, S>(mut self, args: I) -> Self
+ pub fn args<I, S>(&mut self, args: I) -> &mut Self
where
I: Iterator<Item = S>,
S: std::convert::Into<String>,
@@ -47,17 +47,17 @@ impl JoshutoMimetypeEntry {
self
}
- pub fn fork(mut self, fork: bool) -> Self {
+ pub fn fork(&mut self, fork: bool) -> &mut Self {
self._fork = fork;
self
}
- pub fn silent(mut self, silent: bool) -> Self {
+ pub fn silent(&mut self, silent: bool) -> &mut Self {
self._silent = silent;
self
}
- pub fn confirm_exit(mut self, confirm_exit: bool) -> Self {
+ pub fn confirm_exit(&mut self, confirm_exit: bool) -> &mut Self {
self._confirm_exit = confirm_exit;
self
}
diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs
index 806377c..4bda62c 100644
--- a/src/fs/dirlist.rs
+++ b/src/fs/dirlist.rs
@@ -17,8 +17,7 @@ impl JoshutoDirList {
pub fn new(path: path::PathBuf, sort_option: &SortOption) -> std::io::Result<Self> {
let filter_func = sort_option.filter_func();
let mut contents = read_dir_list(path.as_path(), filter_func)?;
- let compare_func = sort_option.compare_func();
- contents.sort_by(compare_func);
+ contents.sort_by(|f1, f2| sort_option.compare(f1, f2));
let index = if contents.is_empty() { None } else { Some(0) };
@@ -48,10 +47,8 @@ impl JoshutoDirList {
pub fn reload_contents(&mut self, sort_option: &SortOption) -> std::io::Result<()> {
let filter_func = sort_option.filter_func();
- let sort_func = sort_option.compare_func();
-
let mut contents = read_dir_list(&self.path, filter_func)?;
- contents.sort_by(sort_func);
+ contents.sort_by(|f1, f2| sort_option.compare(f1, f2));
let contents_len = contents.len();
let index: Option<usize> = if contents_len == 0 {
diff --git a/src/fs/entry.rs b/src/fs/entry.rs
index 80847b4..fbcccb7 100644
--- a/src/fs/entry.rs
+++ b/src/fs/entry.rs
@@ -66,54 +66,6 @@ impl JoshutoDirEntry {
self.selected = selected;
}
- pub fn get_fg_color(&self) -> Color {
- let metadata = &self.metadata;
- let filetype = &metadata.file_type;
-
- if self.is_selected() {
- THEME_T.selection.fg
- } else if filetype.is_dir() {
- THEME_T.directory.fg
- } else if filetype.is_symlink() {
- THEME_T.link.fg
- } else {
- match self.file_path().extension() {
- None => Color::White,
- Some(os_str) => match os_str.to_str() {
- None => Color::White,
- Some(s) => match THEME_T.ext.get(s) {
- None => Color::White,
- Some(t) => t.fg,
- },
- },
- }
- }
- }
-
- pub fn get_bg_color(&self) -> Color {
- let metadata = &self.metadata;
- let filetype = &metadata.file_type;
-
- if self.is_selected() {
- THEME_T.selection.bg
- } else if filetype.is_dir() {
- THEME_T.directory.bg
- } else if filetype.is_symlink() {
- THEME_T.link.bg
- } else {
- match self.file_path().extension() {
- None => Color::Reset,
- Some(os_str) => match os_str.to_str() {
- None => Color::Reset,
- Some(s) => match THEME_T.ext.get(s) {
- None => Color::Reset,
- Some(t) => t.bg,
- },
- },
- }
- }
- }
-
pub fn get_modifier(&self) -> Modifier {
let metadata = &self.metadata;
let filetype = &metadata.file_type;
diff --git a/src/util/sort.rs b/src/util/sort.rs
index 892810b..fcef409 100644
--- a/src/util/sort.rs
+++ b/src/util/sort.rs
@@ -2,16 +2,16 @@ use std::cmp;
use std::fs;
use std::time;
-use crate::fs::JoshutoDirEntry;
-
-use alphanumeric_sort::compare_str;
use serde_derive::Deserialize;
+use crate::fs::JoshutoDirEntry;
+
#[derive(Clone, Copy, Debug, Deserialize)]
pub enum SortType {
Lexical,
Mtime,
Natural,
+ Size,
}
impl SortType {
@@ -20,6 +20,7 @@ impl SortType {
"lexical" => Some(SortType::Lexical),
"mtime" => Some(SortType::Mtime),
"natural" => Some(SortType::Natural),
+ "size" => Some(SortType::Size),
_ => None,
}
}
@@ -28,6 +29,7 @@ impl SortType {
SortType::Lexical => "lexical",
SortType::Mtime => "mtime",
SortType::Natural => "natural",
+ SortType::Size => "size",
}
}
}
@@ -42,38 +44,53 @@ pub struct SortOption {
}
impl SortOption {
- pub fn compare_func(&self) -> impl Fn(&JoshutoDirEntry, &JoshutoDirEntry) -> cmp::Ordering {
- let dir_cmp = if self.directories_first {
- dir_first
- } else {
- dummy_dir_first
- };
-
- let rev_cmp = if self.reverse {
- reverse_ordering
- } else {
- dummy_reverse
- };
+ pub fn compare(&self, f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering {
+ if self.directories_first {
+ let f1_isdir = f1.file_path().is_dir();
+ let f2_isdir = f2.file_path().is_dir();
+
+ if f1_isdir && !f2_isdir {
+ return cmp::Ordering::Less;
+ } else if !f1_isdir && f2_isdir {
+ return cmp::Ordering::Greater;
+ }
+ }
- let base_cmp = match self.sort_method {
- SortType::Natural => {
+ let mut res = match self.sort_method {
+ SortType::Lexical => {
+ let f1_name = f1.file_name();
+ let f2_name = f2.file_name();
if self.case_sensitive {
- natural_sort
+ f1_name.cmp(&f2_name)
} else {
- natural_sort_case_insensitive
+ let f1_name = f1_name.to_lowercase();
+ let f2_name = f2_name.to_lowercase();
+ f1_name.cmp(&f2_name)
}
}
- SortType::Lexical => {
+ SortType::Natural => {
+ let f1_name = f1.file_name();
+ let f2_name = f2.file_name();
if self.case_sensitive {
- natural_sort
+ alphanumeric_sort::compare_str(&f1_name, &f2_name)
} else {
- natural_sort_case_insensitive
+ let f1_name = f1_name.to_lowercase();
+ let f2_name = f2_name.to_lowercase();
+ alphanumeric_sort::compare_str(&f1_name, &f2_name)
}
}
- SortType::Mtime => mtime_sort,
+ SortType::Mtime => mtime_sort(f1, f2),
+ SortType::Size => size_sort(f1, f2),
};
- move |f1, f2| dir_cmp(f1, f2).then_with(|| rev_cmp(base_cmp(f1, f2)))
+ if self.reverse {
+ res = match res {
+ cmp::Ordering::Less => cmp::Ordering::Greater,
+ cmp::Ordering::Greater => cmp::Ordering::Less,
+ s => s,
+ };
+ }
+ return res;
}
pub fn filter_func(&self) -> fn(&Result<fs::DirEntry, std::io::Error>) -> bool {
@@ -115,41 +132,6 @@ fn filter_hidden(result: &Result<fs::DirEntry, std::io::Error>) -> bool {
}
}
-const fn dummy_dir_first(_: &JoshutoDirEntry, _: &JoshutoDirEntry) -> cmp::Ordering {
- cmp::Ordering::Equal
-}
-
-fn dir_first(f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering {
- let f1_isdir = f1.file_path().is_dir();
- let f2_isdir = f2.file_path().is_dir();
-
- if f1_isdir && !f2_isdir {
- cmp::Ordering::Less
- } else if !f1_isdir && f2_isdir {
- cmp::Ordering::Greater
- } else {
- cmp::Ordering::Equal
- }
-}
-
-const fn dummy_reverse(c: cmp::Ordering) -> cmp::Ordering {
- c
-}
-
-fn reverse_ordering(c: cmp::Ordering) -> cmp::Ordering {
- c.reverse()
-}
-
-fn natural_sort_case_insensitive(f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering {
- let f1_name = f1.file_name().to_lowercase();
- let f2_name = f2.file_name().to_lowercase();
- compare_str(&f1_name, &f2_name)
-}
-
-fn natural_sort(f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering {
- compare_str(f1.file_name(), f2.file_name())
-}
-
fn mtime_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering {
fn compare(
file1: &JoshutoDirEntry,
@@ -169,3 +151,7 @@ fn mtime_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering
}
compare(&file1, &file2).unwrap_or(cmp::Ordering::Less)
}
+
+fn size_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering {
+ file1.metadata.len.cmp(&file2.metadata.len)
+}