mirror of
https://github.com/Llewellynvdm/exa.git
synced 2025-02-03 19:18:24 +00:00
Add sorting by type
This isn’t perfect, as a file’s type isn’t cached, so it gets recomputed for every comparison in the sort! We can’t go off the file’s `st_mode` flag because it’s not guaranteed to be in any order between systems.
This commit is contained in:
parent
7d1448da36
commit
f750536420
@ -40,8 +40,11 @@ pub type uid_t = u32;
|
|||||||
/// This type is set entirely by the filesystem, rather than relying on a
|
/// This type is set entirely by the filesystem, rather than relying on a
|
||||||
/// file’s contents. So “link” is a type, but “image” is just a type of
|
/// file’s contents. So “link” is a type, but “image” is just a type of
|
||||||
/// regular file. (See the `filetype` module for those checks.)
|
/// regular file. (See the `filetype` module for those checks.)
|
||||||
|
///
|
||||||
|
/// Its ordering is used when sorting by type.
|
||||||
|
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Type {
|
pub enum Type {
|
||||||
File, Directory, Pipe, Link, Socket, CharDevice, BlockDevice, Special,
|
Directory, File, Link, Pipe, Socket, CharDevice, BlockDevice, Special,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
|
@ -135,6 +135,11 @@ impl FileFilter {
|
|||||||
SortField::AccessedDate => a.metadata.atime().cmp(&b.metadata.atime()),
|
SortField::AccessedDate => a.metadata.atime().cmp(&b.metadata.atime()),
|
||||||
SortField::CreatedDate => a.metadata.ctime().cmp(&b.metadata.ctime()),
|
SortField::CreatedDate => a.metadata.ctime().cmp(&b.metadata.ctime()),
|
||||||
|
|
||||||
|
SortField::FileType => match a.type_char().cmp(&b.type_char()) { // todo: this recomputes
|
||||||
|
Ordering::Equal => natord::compare(&*a.name, &*b.name),
|
||||||
|
order => order,
|
||||||
|
},
|
||||||
|
|
||||||
SortField::Extension(Sensitive) => match a.ext.cmp(&b.ext) {
|
SortField::Extension(Sensitive) => match a.ext.cmp(&b.ext) {
|
||||||
Ordering::Equal => natord::compare(&*a.name, &*b.name),
|
Ordering::Equal => natord::compare(&*a.name, &*b.name),
|
||||||
order => order,
|
order => order,
|
||||||
@ -195,6 +200,12 @@ pub enum SortField {
|
|||||||
/// In original Unix, this was, however, meant as creation time.
|
/// In original Unix, this was, however, meant as creation time.
|
||||||
/// https://www.bell-labs.com/usr/dmr/www/cacm.html
|
/// https://www.bell-labs.com/usr/dmr/www/cacm.html
|
||||||
CreatedDate,
|
CreatedDate,
|
||||||
|
|
||||||
|
/// The type of the file: directories, links, pipes, regular, files, etc.
|
||||||
|
///
|
||||||
|
/// Files are ordered according to the `PartialOrd` implementation of
|
||||||
|
/// `fs::fields::Type`, so changing that will change this.
|
||||||
|
FileType,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether a field should be sorted case-sensitively or case-insensitively.
|
/// Whether a field should be sorted case-sensitively or case-insensitively.
|
||||||
@ -226,7 +237,7 @@ impl SortField {
|
|||||||
|
|
||||||
const SORTS: &[&str] = &[ "name", "Name", "size", "extension",
|
const SORTS: &[&str] = &[ "name", "Name", "size", "extension",
|
||||||
"Extension", "modified", "accessed",
|
"Extension", "modified", "accessed",
|
||||||
"created", "inode", "none" ];
|
"created", "inode", "type", "none" ];
|
||||||
|
|
||||||
if let Some(word) = matches.opt_str("sort") {
|
if let Some(word) = matches.opt_str("sort") {
|
||||||
match &*word {
|
match &*word {
|
||||||
@ -238,8 +249,9 @@ impl SortField {
|
|||||||
"mod" | "modified" => Ok(SortField::ModifiedDate),
|
"mod" | "modified" => Ok(SortField::ModifiedDate),
|
||||||
"acc" | "accessed" => Ok(SortField::AccessedDate),
|
"acc" | "accessed" => Ok(SortField::AccessedDate),
|
||||||
"cr" | "created" => Ok(SortField::CreatedDate),
|
"cr" | "created" => Ok(SortField::CreatedDate),
|
||||||
"none" => Ok(SortField::Unsorted),
|
|
||||||
"inode" => Ok(SortField::FileInode),
|
"inode" => Ok(SortField::FileInode),
|
||||||
|
"type" => Ok(SortField::FileType),
|
||||||
|
"none" => Ok(SortField::Unsorted),
|
||||||
field => Err(Misfire::bad_argument("sort", field, SORTS))
|
field => Err(Misfire::bad_argument("sort", field, SORTS))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,14 +85,19 @@ $exa $testcases/file-names-exts -1 2>&1 --sort=name | diff -q - $results/file-na
|
|||||||
$exa $testcases/file-names-exts -1 2>&1 --sort=Ext | diff -q - $results/file-names-exts-ext || exit 1
|
$exa $testcases/file-names-exts -1 2>&1 --sort=Ext | diff -q - $results/file-names-exts-ext || exit 1
|
||||||
$exa $testcases/file-names-exts -1 2>&1 --sort=ext | diff -q - $results/file-names-exts-ext-case || exit 1
|
$exa $testcases/file-names-exts -1 2>&1 --sort=ext | diff -q - $results/file-names-exts-ext-case || exit 1
|
||||||
|
|
||||||
|
# Pass multiple input arguments because there aren’t enough of different types
|
||||||
|
# in one directory already
|
||||||
|
$exa $testcases/links -1 --sort=type 2>&1 | diff -q - $results/sort-by-type || exit 1
|
||||||
|
|
||||||
# We can’t guarantee inode numbers, but we can at least check that they’re in
|
# We can’t guarantee inode numbers, but we can at least check that they’re in
|
||||||
# order. The inode column is the leftmost one, so sort works for this.
|
# order. The inode column is the leftmost one, so sort works for this.
|
||||||
$exa $testcases/file-names-exts --long --inode --sort=inode | sort --check || exit 1
|
$exa $testcases/file-names-exts --long --inode --sort=inode | sort --check || exit 1
|
||||||
|
|
||||||
|
|
||||||
# Other file types
|
# Other file types
|
||||||
$exa $testcases/specials -l 2>&1 | diff -q - $results/specials || exit 1
|
$exa $testcases/specials -l 2>&1 | diff -q - $results/specials || exit 1
|
||||||
$exa $testcases/specials -F -l 2>&1 | diff -q - $results/specials_F || exit 1
|
$exa $testcases/specials -F -l 2>&1 | diff -q - $results/specials_F || exit 1
|
||||||
|
$exa $testcases/specials --sort=type -1 2>&1 | diff -q - $results/specials_sort || exit 1
|
||||||
|
|
||||||
|
|
||||||
# Ignores
|
# Ignores
|
||||||
|
10
xtests/sort-by-type
Normal file
10
xtests/sort-by-type
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
some_file
|
||||||
|
[36mbroken[0m [31m->[0m [4;31mnowhere[0m
|
||||||
|
[36mcurrent_dir[0m [38;5;244m->[0m [1;34m.[0m
|
||||||
|
[36mforbidden[0m [31m->[0m [4;31m/proc/1/root[0m
|
||||||
|
[36mitself[0m [31m->[0m [4;31mitself[0m
|
||||||
|
[36mparent_dir[0m [38;5;244m->[0m [1;34m..[0m
|
||||||
|
[36mroot[0m [38;5;244m->[0m [1;34m/[0m
|
||||||
|
[36msome_file_absolute[0m [38;5;244m->[0m [36m/testcases/links/[0msome_file
|
||||||
|
[36msome_file_relative[0m [38;5;244m->[0m some_file
|
||||||
|
[36musr[0m [38;5;244m->[0m [36m/[1;34musr[0m
|
3
xtests/specials_sort
Normal file
3
xtests/specials_sort
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[33mnamed-pipe[0m
|
||||||
|
[1;33mchar-device[0m
|
||||||
|
[1;33mblock-device[0m
|
Loading…
x
Reference in New Issue
Block a user