summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authormakeefu <makeefu@ya.ru>2021-05-17 11:49:45 +0300
committermakeefu <makeefu@ya.ru>2021-05-17 11:49:45 +0300
commitd205431ee15c5dee82990b4889db3794a5151426 (patch)
treeb83956bddee48d40e1a5f36aac97b8984269d871 /src
parente65cdccf066b85caa9590d52daa0e37189958e49 (diff)
some sorting features added
Diffstat (limited to 'src')
-rw-r--r--src/commands/sort.rs6
-rw-r--r--src/config/default/sort.rs11
-rw-r--r--src/fs/entry.rs9
-rw-r--r--src/util/sort.rs128
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)
+ }
+}