diff options
author | makeefu <makeefu@ya.ru> | 2021-05-17 11:49:45 +0300 |
---|---|---|
committer | makeefu <makeefu@ya.ru> | 2021-05-17 11:49:45 +0300 |
commit | d205431ee15c5dee82990b4889db3794a5151426 (patch) | |
tree | b83956bddee48d40e1a5f36aac97b8984269d871 /src | |
parent | e65cdccf066b85caa9590d52daa0e37189958e49 (diff) |
some sorting features added
Diffstat (limited to 'src')
-rw-r--r-- | src/commands/sort.rs | 6 | ||||
-rw-r--r-- | src/config/default/sort.rs | 11 | ||||
-rw-r--r-- | src/fs/entry.rs | 9 | ||||
-rw-r--r-- | src/util/sort.rs | 128 |
4 files changed, 123 insertions, 31 deletions
diff --git a/src/commands/sort.rs b/src/commands/sort.rs index 161f2ba..58ffd2e 100644 --- a/src/commands/sort.rs +++ b/src/commands/sort.rs @@ -8,8 +8,10 @@ use crate::util::sort::SortType; use super::reload; pub fn set_sort(context: &mut AppContext, method: SortType) -> JoshutoResult<()> { - context.config_mut().sort_options_mut().sort_method = method; - + context + .config_mut() + .sort_options_mut() + .set_sort_method(method); for tab in context.tab_context_mut().iter_mut() { tab.history_mut().depreciate_all_entries(); } diff --git a/src/config/default/sort.rs b/src/config/default/sort.rs index 4ce5133..bda7ee9 100644 --- a/src/config/default/sort.rs +++ b/src/config/default/sort.rs @@ -1,6 +1,7 @@ use serde_derive::Deserialize; use crate::util::sort; +use crate::util::sort::SortType; const fn default_true() -> bool { true @@ -24,11 +25,21 @@ impl SortRawOption { Some(s) => sort::SortType::parse(s).unwrap_or(sort::SortType::Natural), None => sort::SortType::Natural, }; + + let mut sort_methods = std::collections::LinkedList::new(); + sort_methods.push_back(SortType::Ext); + sort_methods.push_back(SortType::Size); + sort_methods.push_back(SortType::Mtime); + sort_methods.push_back(SortType::Lexical); + sort_methods.push_back(SortType::Natural); + + let sort_methods = sort::SortTypes { list: sort_methods }; sort::SortOption { directories_first: self.directories_first, case_sensitive: self.case_sensitive, reverse: self.reverse, sort_method, + sort_methods, } } } diff --git a/src/fs/entry.rs b/src/fs/entry.rs index 9c17ff4..71f0aee 100644 --- a/src/fs/entry.rs +++ b/src/fs/entry.rs @@ -86,6 +86,15 @@ impl JoshutoDirEntry { pub fn set_selected(&mut self, selected: bool) { self.selected = selected; } + + pub fn get_ext(&self) -> &str { + let fname = self.file_name(); + let ext = match fname.rfind('.') { + Some(pos) => &fname[pos..], + None => &fname[0..0], + }; + ext + } } impl std::fmt::Display for JoshutoDirEntry { diff --git a/src/util/sort.rs b/src/util/sort.rs index 37294dd..f94cc8b 100644 --- a/src/util/sort.rs +++ b/src/util/sort.rs @@ -6,12 +6,40 @@ use serde_derive::Deserialize; use crate::fs::JoshutoDirEntry; -#[derive(Clone, Copy, Debug, Deserialize)] +#[derive(Clone, Debug)] +pub struct SortTypes { + pub list: std::collections::LinkedList<SortType>, +} + +impl SortTypes { + pub fn reorganize(&mut self, st: SortType) { + self.list.push_front(st); + self.list.pop_back(); + } + + pub fn cmp( + &self, + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, + ) -> cmp::Ordering { + for st in &self.list { + let res = st.cmp(f1, f2, sort_option); + if res != cmp::Ordering::Equal { + return res; + } + } + cmp::Ordering::Equal + } +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq)] pub enum SortType { Lexical, Mtime, Natural, Size, + Ext, } impl SortType { @@ -21,6 +49,7 @@ impl SortType { "mtime" => Some(SortType::Mtime), "natural" => Some(SortType::Natural), "size" => Some(SortType::Size), + "ext" => Some(SortType::Ext), _ => None, } } @@ -30,8 +59,24 @@ impl SortType { SortType::Mtime => "mtime", SortType::Natural => "natural", SortType::Size => "size", + SortType::Ext => "ext", } } + pub fn cmp( + &self, + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, + ) -> cmp::Ordering { + let res = match &self { + SortType::Natural => natural_sort(f1, f2, sort_option), + SortType::Lexical => lexical_sort(f1, f2, sort_option), + SortType::Size => size_sort(f1, f2), + SortType::Mtime => mtime_sort(f1, f2), + SortType::Ext => ext_sort(f1, f2), + }; + return res; + } } impl std::fmt::Display for SortType { @@ -46,9 +91,14 @@ pub struct SortOption { pub case_sensitive: bool, pub reverse: bool, pub sort_method: SortType, + pub sort_methods: SortTypes, } impl SortOption { + pub fn set_sort_method(&mut self, method: SortType) { + self.sort_methods.reorganize(method); + } + pub fn compare(&self, f1: &JoshutoDirEntry, f2: &JoshutoDirEntry) -> cmp::Ordering { if self.directories_first { let f1_isdir = f1.file_path().is_dir(); @@ -61,51 +111,33 @@ impl SortOption { } } - 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 { - f1_name.cmp(&f2_name) - } else { - let f1_name = f1_name.to_lowercase(); - let f2_name = f2_name.to_lowercase(); - f1_name.cmp(&f2_name) - } - } - SortType::Natural => { - let f1_name = f1.file_name(); - let f2_name = f2.file_name(); - if self.case_sensitive { - alphanumeric_sort::compare_str(&f1_name, &f2_name) - } else { - 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(f1, f2), - SortType::Size => size_sort(f1, f2), - }; - + // let mut res = self.sort_method.cmp(f1, f2, &self); + let mut res = self.sort_methods.cmp(f1, f2, &self); if self.reverse { res = match res { cmp::Ordering::Less => cmp::Ordering::Greater, cmp::Ordering::Greater => cmp::Ordering::Less, s => s, }; - } + }; res } } impl std::default::Default for SortOption { fn default() -> Self { + let mut sort_methods = std::collections::LinkedList::new(); + sort_methods.push_back(SortType::Ext); + sort_methods.push_back(SortType::Size); + sort_methods.push_back(SortType::Mtime); + sort_methods.push_back(SortType::Lexical); + sort_methods.push_back(SortType::Natural); SortOption { directories_first: true, case_sensitive: false, reverse: false, sort_method: SortType::Natural, + sort_methods: SortTypes { list: sort_methods }, } } } @@ -133,3 +165,41 @@ fn mtime_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering fn size_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { file1.metadata.len().cmp(&file2.metadata.len()) } + +fn ext_sort(file1: &JoshutoDirEntry, file2: &JoshutoDirEntry) -> cmp::Ordering { + let f1_ext = file1.get_ext(); + let f2_ext = file2.get_ext(); + alphanumeric_sort::compare_str(&f1_ext, &f2_ext) +} + +fn lexical_sort( + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, +) -> cmp::Ordering { + let f1_name = f1.file_name(); + let f2_name = f2.file_name(); + if sort_option.case_sensitive { + f1_name.cmp(&f2_name) + } else { + let f1_name = f1_name.to_lowercase(); + let f2_name = f2_name.to_lowercase(); + f1_name.cmp(&f2_name) + } +} + +fn natural_sort( + f1: &JoshutoDirEntry, + f2: &JoshutoDirEntry, + sort_option: &SortOption, +) -> cmp::Ordering { + let f1_name = f1.file_name(); + let f2_name = f2.file_name(); + if sort_option.case_sensitive { + alphanumeric_sort::compare_str(&f1_name, &f2_name) + } else { + let f1_name = f1_name.to_lowercase(); + let f2_name = f2_name.to_lowercase(); + alphanumeric_sort::compare_str(&f1_name, &f2_name) + } +} |