mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
feat: prepare for natural sort
This commit is contained in:
parent
a7a085e41c
commit
c6eb52b457
3 changed files with 40 additions and 21 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
- `"alphabetical"`: Sort alphabetically
|
- `"alphabetical"`: Sort alphabetically
|
||||||
- `"created"`: Sort by creation time
|
- `"created"`: Sort by creation time
|
||||||
- `"modified"`: Sort by last modified time
|
- `"modified"`: Sort by last modified time
|
||||||
|
- `"natural"`: Sort naturally
|
||||||
- `"size"`: Sort by file size
|
- `"size"`: Sort by file size
|
||||||
|
|
||||||
- sort_reverse: Display files in reverse order
|
- sort_reverse: Display files in reverse order
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ pub enum SortBy {
|
||||||
Alphabetical,
|
Alphabetical,
|
||||||
Created,
|
Created,
|
||||||
Modified,
|
Modified,
|
||||||
|
Natural,
|
||||||
Size,
|
Size,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -19,6 +20,7 @@ impl TryFrom<String> for SortBy {
|
||||||
"alphabetical" => Self::Alphabetical,
|
"alphabetical" => Self::Alphabetical,
|
||||||
"created" => Self::Created,
|
"created" => Self::Created,
|
||||||
"modified" => Self::Modified,
|
"modified" => Self::Modified,
|
||||||
|
"natural" => Self::Natural,
|
||||||
"size" => Self::Size,
|
"size" => Self::Size,
|
||||||
_ => bail!("invalid sort_by value: {s}"),
|
_ => bail!("invalid sort_by value: {s}"),
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
use std::{cmp::Ordering, collections::BTreeMap, ops::{Deref, DerefMut}, path::{Path, PathBuf}};
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
|
collections::BTreeMap,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use config::{manager::SortBy, MANAGER};
|
use config::{manager::SortBy, MANAGER};
|
||||||
|
|
@ -8,18 +13,14 @@ use tokio::fs;
|
||||||
use super::File;
|
use super::File;
|
||||||
|
|
||||||
pub struct Files {
|
pub struct Files {
|
||||||
items: IndexMap<PathBuf, File>,
|
items: IndexMap<PathBuf, File>,
|
||||||
pub sort: FilesSort,
|
pub sort: FilesSort,
|
||||||
pub show_hidden: bool,
|
pub show_hidden: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Files {
|
impl Default for Files {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self { items: Default::default(), sort: Default::default(), show_hidden: MANAGER.show_hidden }
|
||||||
items: Default::default(),
|
|
||||||
sort: Default::default(),
|
|
||||||
show_hidden: MANAGER.show_hidden,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,13 +123,21 @@ impl Files {
|
||||||
if promote != Ordering::Equal {
|
if promote != Ordering::Equal {
|
||||||
promote
|
promote
|
||||||
} else {
|
} else {
|
||||||
if reverse { b.cmp(&a) } else { a.cmp(&b) }
|
if reverse {
|
||||||
|
b.cmp(&a)
|
||||||
|
} else {
|
||||||
|
a.cmp(&b)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn promote(a: &File, b: &File, dir_first: bool) -> Ordering {
|
fn promote(a: &File, b: &File, dir_first: bool) -> Ordering {
|
||||||
if dir_first { b.meta.is_dir().cmp(&a.meta.is_dir()) } else { Ordering::Equal }
|
if dir_first {
|
||||||
|
b.meta.is_dir().cmp(&a.meta.is_dir())
|
||||||
|
} else {
|
||||||
|
Ordering::Equal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let reverse = self.sort.reverse;
|
let reverse = self.sort.reverse;
|
||||||
|
|
@ -149,6 +158,9 @@ impl Files {
|
||||||
}
|
}
|
||||||
Ordering::Equal
|
Ordering::Equal
|
||||||
}),
|
}),
|
||||||
|
SortBy::Natural => {
|
||||||
|
self.items.sort_by(|_, a, _, b| cmp(&a.path, &b.path, reverse, promote(a, b, dir_first)))
|
||||||
|
}
|
||||||
SortBy::Size => self.items.sort_by(|_, a, _, b| {
|
SortBy::Size => self.items.sort_by(|_, a, _, b| {
|
||||||
cmp(a.length.unwrap_or(0), b.length.unwrap_or(0), reverse, promote(a, b, dir_first))
|
cmp(a.length.unwrap_or(0), b.length.unwrap_or(0), reverse, promote(a, b, dir_first))
|
||||||
}),
|
}),
|
||||||
|
|
@ -160,27 +172,27 @@ impl Files {
|
||||||
impl Deref for Files {
|
impl Deref for Files {
|
||||||
type Target = IndexMap<PathBuf, File>;
|
type Target = IndexMap<PathBuf, File>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target { &self.items }
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.items
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for Files {
|
impl DerefMut for Files {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target { &mut self.items }
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.items
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct FilesSort {
|
pub struct FilesSort {
|
||||||
pub by: SortBy,
|
pub by: SortBy,
|
||||||
pub reverse: bool,
|
pub reverse: bool,
|
||||||
pub dir_first: bool,
|
pub dir_first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FilesSort {
|
impl Default for FilesSort {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self { by: MANAGER.sort_by, reverse: MANAGER.sort_reverse, dir_first: MANAGER.sort_dir_first }
|
||||||
by: MANAGER.sort_by,
|
|
||||||
reverse: MANAGER.sort_reverse,
|
|
||||||
dir_first: MANAGER.sort_dir_first,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,8 +217,12 @@ impl FilesOp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn read_empty(path: &Path) -> Self { Self::Read(path.to_path_buf(), BTreeMap::new()) }
|
pub fn read_empty(path: &Path) -> Self {
|
||||||
|
Self::Read(path.to_path_buf(), BTreeMap::new())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn search_empty(path: &Path) -> Self { Self::Search(path.to_path_buf(), BTreeMap::new()) }
|
pub fn search_empty(path: &Path) -> Self {
|
||||||
|
Self::Search(path.to_path_buf(), BTreeMap::new())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue