diff options
-rw-r--r-- | src/config/mimetype.rs | 10 | ||||
-rw-r--r-- | src/fs/dirlist.rs | 7 | ||||
-rw-r--r-- | src/fs/entry.rs | 48 | ||||
-rw-r--r-- | src/util/sort.rs | 104 |
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) +} |