mirror of
https://github.com/sxyazi/yazi.git
synced 2024-12-20 07:11:33 +03:00
feat: file size sorting under the simplified file system (#123)
This commit is contained in:
parent
d702cbcf9a
commit
fa64047120
@ -14,7 +14,7 @@ impl<'a> Left<'a> {
|
|||||||
|
|
||||||
impl<'a> Widget for Left<'a> {
|
impl<'a> Widget for Left<'a> {
|
||||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||||
let manager = self.cx.manager.current();
|
let folder = self.cx.manager.current();
|
||||||
let mode = self.cx.manager.active().mode();
|
let mode = self.cx.manager.active().mode();
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
@ -33,10 +33,14 @@ impl<'a> Widget for Left<'a> {
|
|||||||
primary.bg().fg(**secondary).add_modifier(Modifier::BOLD),
|
primary.bg().fg(**secondary).add_modifier(Modifier::BOLD),
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Some(h) = &manager.hovered {
|
if let Some(h) = &folder.hovered {
|
||||||
// Length
|
// Length
|
||||||
if let Some(len) = h.length() {
|
{
|
||||||
spans.push(Span::styled(format!(" {} ", readable_size(len)), body.bg().fg(**primary)));
|
let size = if h.is_dir() { folder.files.size(h.url()) } else { None };
|
||||||
|
spans.push(Span::styled(
|
||||||
|
format!(" {} ", readable_size(size.unwrap_or(h.length()))),
|
||||||
|
body.bg().fg(**primary),
|
||||||
|
));
|
||||||
spans.push(Span::styled(&separator.closing, body.fg()));
|
spans.push(Span::styled(&separator.closing, body.fg()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ use tokio::fs;
|
|||||||
pub struct File {
|
pub struct File {
|
||||||
pub(super) url: Url,
|
pub(super) url: Url,
|
||||||
pub(super) meta: Metadata,
|
pub(super) meta: Metadata,
|
||||||
pub(super) length: Option<u64>,
|
pub(super) length: u64,
|
||||||
pub(super) link_to: Option<Url>,
|
pub(super) link_to: Option<Url>,
|
||||||
pub(super) is_link: bool,
|
pub(super) is_link: bool,
|
||||||
pub(super) is_hidden: bool,
|
pub(super) is_hidden: bool,
|
||||||
@ -30,7 +30,7 @@ impl File {
|
|||||||
link_to = fs::read_link(&url).await.map(Url::from).ok();
|
link_to = fs::read_link(&url).await.map(Url::from).ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
let length = if meta.is_dir() { None } else { Some(meta.len()) };
|
let length = meta.len();
|
||||||
let is_hidden = url.file_name().map(|s| s.to_string_lossy().starts_with('.')).unwrap_or(false);
|
let is_hidden = url.file_name().map(|s| s.to_string_lossy().starts_with('.')).unwrap_or(false);
|
||||||
Self { url, meta, length, link_to, is_link, is_hidden }
|
Self { url, meta, length, link_to, is_link, is_hidden }
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ impl File {
|
|||||||
|
|
||||||
// --- Length
|
// --- Length
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn length(&self) -> Option<u64> { self.length }
|
pub fn length(&self) -> u64 { self.length }
|
||||||
|
|
||||||
// --- Link to
|
// --- Link to
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -126,7 +126,7 @@ impl Files {
|
|||||||
if !self.show_hidden {
|
if !self.show_hidden {
|
||||||
(self.hidden, items) = items.into_iter().partition(|f| f.is_hidden);
|
(self.hidden, items) = items.into_iter().partition(|f| f.is_hidden);
|
||||||
}
|
}
|
||||||
self.sorter.sort(&mut items);
|
self.sorter.sort(&mut items, &self.sizes);
|
||||||
self.items = items;
|
self.items = items;
|
||||||
self.version = FILES_VERSION.fetch_add(1, Ordering::Relaxed);
|
self.version = FILES_VERSION.fetch_add(1, Ordering::Relaxed);
|
||||||
true
|
true
|
||||||
@ -146,7 +146,7 @@ impl Files {
|
|||||||
self.hidden.extend(hidden);
|
self.hidden.extend(hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sorter.sort(&mut self.items);
|
self.sorter.sort(&mut self.items, &self.sizes);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ impl Files {
|
|||||||
pub fn update_size(&mut self, items: BTreeMap<Url, u64>) -> bool {
|
pub fn update_size(&mut self, items: BTreeMap<Url, u64>) -> bool {
|
||||||
self.sizes.extend(items);
|
self.sizes.extend(items);
|
||||||
if self.sorter.by == SortBy::Size {
|
if self.sorter.by == SortBy::Size {
|
||||||
self.sorter.sort(&mut self.items);
|
self.sorter.sort(&mut self.items, &self.sizes);
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -186,6 +186,10 @@ impl Files {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn duplicate(&self, idx: usize) -> Option<File> { self.items.get(idx).cloned() }
|
pub fn duplicate(&self, idx: usize) -> Option<File> { self.items.get(idx).cloned() }
|
||||||
|
|
||||||
|
// --- Size
|
||||||
|
#[inline]
|
||||||
|
pub fn size(&self, url: &Url) -> Option<u64> { self.sizes.get(url).copied() }
|
||||||
|
|
||||||
// --- Selected
|
// --- Selected
|
||||||
pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> {
|
pub fn selected(&self, pending: &BTreeSet<usize>, unset: bool) -> Vec<&File> {
|
||||||
if self.selected.is_empty() && (unset || pending.is_empty()) {
|
if self.selected.is_empty() && (unset || pending.is_empty()) {
|
||||||
@ -234,7 +238,7 @@ impl Files {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
self.sorter = sorter;
|
self.sorter = sorter;
|
||||||
self.sorter.sort(&mut self.items)
|
self.sorter.sort(&mut self.items, &self.sizes)
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Show hidden
|
// --- Show hidden
|
||||||
@ -248,7 +252,7 @@ impl Files {
|
|||||||
|
|
||||||
if state {
|
if state {
|
||||||
self.items.append(&mut self.hidden);
|
self.items.append(&mut self.hidden);
|
||||||
self.sorter.sort(&mut self.items);
|
self.sorter.sort(&mut self.items, &self.sizes);
|
||||||
} else {
|
} else {
|
||||||
let items = mem::take(&mut self.items);
|
let items = mem::take(&mut self.items);
|
||||||
(self.hidden, self.items) = items.into_iter().partition(|f| f.is_hidden);
|
(self.hidden, self.items) = items.into_iter().partition(|f| f.is_hidden);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use std::{cmp::Ordering, mem};
|
use std::{cmp::Ordering, collections::BTreeMap, mem};
|
||||||
|
|
||||||
use config::{manager::SortBy, MANAGER};
|
use config::{manager::SortBy, MANAGER};
|
||||||
|
use shared::Url;
|
||||||
|
|
||||||
use super::File;
|
use super::File;
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ impl Default for FilesSorter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FilesSorter {
|
impl FilesSorter {
|
||||||
pub(super) fn sort(&self, items: &mut Vec<File>) -> bool {
|
pub(super) fn sort(&self, items: &mut Vec<File>, sizes: &BTreeMap<Url, u64>) -> bool {
|
||||||
if items.is_empty() {
|
if items.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -45,7 +46,9 @@ impl FilesSorter {
|
|||||||
}),
|
}),
|
||||||
SortBy::Natural => self.sort_naturally(items),
|
SortBy::Natural => self.sort_naturally(items),
|
||||||
SortBy::Size => items.sort_unstable_by(|a, b| {
|
SortBy::Size => items.sort_unstable_by(|a, b| {
|
||||||
self.cmp(a.length().unwrap_or(0), b.length().unwrap_or(0), self.promote(a, b))
|
let aa = if a.is_dir() { sizes.get(a.url()).copied() } else { None };
|
||||||
|
let bb = if b.is_dir() { sizes.get(b.url()).copied() } else { None };
|
||||||
|
self.cmp(aa.unwrap_or(a.length), bb.unwrap_or(b.length), self.promote(a, b))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
@ -73,7 +76,7 @@ impl FilesSorter {
|
|||||||
let dummy = File {
|
let dummy = File {
|
||||||
url: Default::default(),
|
url: Default::default(),
|
||||||
meta: items[0].meta.clone(),
|
meta: items[0].meta.clone(),
|
||||||
length: None,
|
length: 0,
|
||||||
link_to: None,
|
link_to: None,
|
||||||
is_link: false,
|
is_link: false,
|
||||||
is_hidden: false,
|
is_hidden: false,
|
||||||
|
@ -211,8 +211,11 @@ impl Tasks {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
let targets: Vec<_> =
|
let targets: Vec<_> = targets
|
||||||
targets.iter().filter(|f| f.is_dir() && f.length().is_none()).map(|f| f.url()).collect();
|
.iter()
|
||||||
|
.filter(|f| f.is_dir() && targets.size(f.url()).is_none())
|
||||||
|
.map(|f| f.url())
|
||||||
|
.collect();
|
||||||
|
|
||||||
if !targets.is_empty() {
|
if !targets.is_empty() {
|
||||||
self.scheduler.precache_size(targets);
|
self.scheduler.precache_size(targets);
|
||||||
|
Loading…
Reference in New Issue
Block a user