refactor: privatize url of the File (#1619)

This commit is contained in:
三咲雅 · Misaki Masa 2024-09-10 00:31:21 +08:00 committed by GitHub
parent 9483798459
commit d20b3d8408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 115 additions and 113 deletions

View file

@ -18,7 +18,7 @@ impl Filetype {
} }
self.mime.as_ref().is_some_and(|p| p.match_mime(mime)) self.mime.as_ref().is_some_and(|p| p.match_mime(mime))
|| self.name.as_ref().is_some_and(|n| n.match_path(&file.url, file.is_dir())) || self.name.as_ref().is_some_and(|n| n.match_path(file.url(), file.is_dir()))
} }
} }

View file

@ -43,12 +43,12 @@ impl Icons {
#[inline] #[inline]
fn match_by_glob(&self, file: &File) -> Option<&Icon> { fn match_by_glob(&self, file: &File) -> Option<&Icon> {
self.globs.iter().find(|(p, _)| p.match_path(&file.url, file.is_dir())).map(|(_, i)| i) self.globs.iter().find(|(p, _)| p.match_path(file.url(), file.is_dir())).map(|(_, i)| i)
} }
#[inline] #[inline]
fn match_by_name(&self, file: &File) -> Option<&Icon> { fn match_by_name(&self, file: &File) -> Option<&Icon> {
let name = file.name()?.to_str()?; let name = file.name().to_str()?;
if file.is_dir() { if file.is_dir() {
self.dirs.get(name).or_else(|| self.dirs.get(&name.to_ascii_lowercase())) self.dirs.get(name).or_else(|| self.dirs.get(&name.to_ascii_lowercase()))
} else { } else {
@ -62,7 +62,7 @@ impl Icons {
#[inline] #[inline]
fn match_by_ext(&self, file: &File) -> Option<&Icon> { fn match_by_ext(&self, file: &File) -> Option<&Icon> {
let ext = file.url.extension()?.to_str()?; let ext = file.url().extension()?.to_str()?;
self.exts.get(ext).or_else(|| self.exts.get(&ext.to_ascii_lowercase())) self.exts.get(ext).or_else(|| self.exts.get(&ext.to_ascii_lowercase()))
} }
} }

View file

@ -96,7 +96,7 @@ impl Manager {
} }
if !succeeded.is_empty() { if !succeeded.is_empty() {
Pubsub::pub_from_bulk(succeeded.iter().map(|(u, f)| (u, &f.url)).collect()); Pubsub::pub_from_bulk(succeeded.iter().map(|(u, f)| (u, f.url())).collect());
FilesOp::Upserting(cwd, succeeded).emit(); FilesOp::Upserting(cwd, succeeded).emit();
} }
drop(permit); drop(permit);

View file

@ -59,7 +59,7 @@ impl Manager {
} }
if let Ok(f) = File::from(new.clone()).await { if let Ok(f) = File::from(new.clone()).await {
FilesOp::Upserting(parent, HashMap::from_iter([(f.url(), f)])).emit(); FilesOp::Upserting(parent, HashMap::from_iter([(f.url_owned(), f)])).emit();
TabProxy::reveal(&new) TabProxy::reveal(&new)
} }
Ok(()) Ok(())

View file

@ -28,7 +28,7 @@ impl Manager {
// Hover on the file // Hover on the file
render!(self.current_or_mut(opt.tab).repos(opt.url.as_ref())); render!(self.current_or_mut(opt.tab).repos(opt.url.as_ref()));
if opt.url.zip(self.current_or(opt.tab).hovered()).is_some_and(|(u, f)| u == f.url) { if opt.url.zip(self.current_or(opt.tab).hovered()).is_some_and(|(u, f)| &u == f.url()) {
// `hover(Some)` occurs after user actions, such as create, rename, reveal, etc. // `hover(Some)` occurs after user actions, such as create, rename, reveal, etc.
// At this point, it's intuitive to track the location of this file regardless. // At this point, it's intuitive to track the location of this file regardless.
self.current_or_mut(opt.tab).tracing = true; self.current_or_mut(opt.tab).tracing = true;
@ -45,12 +45,12 @@ impl Manager {
to_watch.insert(&p.cwd); to_watch.insert(&p.cwd);
} }
if let Some(h) = tab.current.hovered().filter(|&h| h.is_dir()) { if let Some(h) = tab.current.hovered().filter(|&h| h.is_dir()) {
to_watch.insert(&h.url); to_watch.insert(h.url());
} }
} }
self.watcher.watch(to_watch); self.watcher.watch(to_watch);
// Publish through DDS // Publish through DDS
Pubsub::pub_from_hover(self.active().idx, self.hovered().map(|h| &h.url)); Pubsub::pub_from_hover(self.active().idx, self.hovered().map(|h| h.url()));
} }
} }

View file

@ -27,7 +27,7 @@ impl Manager {
if !self.active_mut().try_escape_visual() { if !self.active_mut().try_escape_visual() {
return; return;
} }
let Some(hovered) = self.hovered().map(|h| h.url()) else { let Some(hovered) = self.hovered().map(|h| h.url_owned()) else {
return; return;
}; };
@ -63,7 +63,7 @@ impl Manager {
} }
} }
done.extend(files.iter().map(|f| (f.url(), String::new()))); done.extend(files.iter().map(|f| (f.url_owned(), String::new())));
if let Err(e) = isolate::fetch("mime", files).await { if let Err(e) = isolate::fetch("mime", files).await {
error!("Fetch `mime` failed in opening: {e}"); error!("Fetch `mime` failed in opening: {e}");
} }
@ -111,7 +111,7 @@ impl Manager {
let find = |folder: Option<&Folder>| { let find = |folder: Option<&Folder>| {
folder.is_some_and(|folder| { folder.is_some_and(|folder| {
folder.cwd == p && folder.files.iter().any(|f| f.is_dir() && f.url == *url) folder.cwd == p && folder.files.iter().any(|f| f.is_dir() && url == f.url())
}) })
}; };

View file

@ -31,13 +31,13 @@ impl Manager {
}; };
let folder = self.active().hovered_folder().map(|f| (f.offset, f.cha)); let folder = self.active().hovered_folder().map(|f| (f.offset, f.cha));
if !self.active().preview.same_url(&hovered.url) { if !self.active().preview.same_url(hovered.url()) {
self.active_mut().preview.skip = folder.map(|f| f.0).unwrap_or_default(); self.active_mut().preview.skip = folder.map(|f| f.0).unwrap_or_default();
render!(self.active_mut().preview.reset()); render!(self.active_mut().preview.reset());
} }
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
if matches!(opt.only_if, Some(ref u) if *u != hovered.url) { if matches!(opt.only_if, Some(ref u) if u != hovered.url()) {
return; return;
} }
@ -55,7 +55,7 @@ impl Manager {
return; return;
} }
let mime = self.mimetype.get(&hovered.url).cloned().unwrap_or_default(); let mime = self.mimetype.get(hovered.url()).cloned().unwrap_or_default();
if !mime.is_empty() { if !mime.is_empty() {
// Wait till mimetype is resolved to avoid flickering // Wait till mimetype is resolved to avoid flickering
self.active_mut().preview.go(hovered, &mime, opt.force); self.active_mut().preview.go(hovered, &mime, opt.force);

View file

@ -27,7 +27,7 @@ impl Manager {
if !self.active_mut().try_escape_visual() { if !self.active_mut().try_escape_visual() {
return; return;
} }
let Some(hovered) = self.hovered().map(|h| &h.url) else { let Some(hovered) = self.hovered().map(|h| h.url()) else {
return; return;
}; };

View file

@ -32,7 +32,7 @@ impl Manager {
if !self.active_mut().try_escape_visual() { if !self.active_mut().try_escape_visual() {
return; return;
} }
let Some(hovered) = self.hovered().map(|h| h.url()) else { let Some(hovered) = self.hovered().map(|h| h.url_owned()) else {
return; return;
}; };

View file

@ -21,13 +21,13 @@ impl Manager {
let mime = if hovered.is_dir() { let mime = if hovered.is_dir() {
MIME_DIR MIME_DIR
} else if let Some(s) = self.mimetype.get(&hovered.url) { } else if let Some(s) = self.mimetype.get(hovered.url()) {
s s
} else { } else {
return render!(self.active_mut().preview.reset()); return render!(self.active_mut().preview.reset());
}; };
let Some(previewer) = PLUGIN.previewer(&hovered.url, mime) else { let Some(previewer) = PLUGIN.previewer(hovered.url(), mime) else {
return render!(self.active_mut().preview.reset()); return render!(self.active_mut().preview.reset());
}; };

View file

@ -42,7 +42,7 @@ impl Tabs {
} else if let Some(h) = self.active().current.hovered() { } else if let Some(h) = self.active().current.hovered() {
tab.conf = self.active().conf.clone(); tab.conf = self.active().conf.clone();
tab.apply_files_attrs(); tab.apply_files_attrs();
tab.reveal(h.url.to_owned()); tab.reveal(h.url_owned());
} else { } else {
tab.conf = self.active().conf.clone(); tab.conf = self.active().conf.clone();
tab.apply_files_attrs(); tab.apply_files_attrs();

View file

@ -51,7 +51,7 @@ impl Manager {
Self::update_current(tab, op, tasks); Self::update_current(tab, op, tasks);
} else if matches!(&tab.parent, Some(p) if p.cwd == *url) { } else if matches!(&tab.parent, Some(p) if p.cwd == *url) {
Self::update_parent(tab, op); Self::update_parent(tab, op);
} else if matches!(tab.current.hovered(), Some(h) if h.url == *url) { } else if matches!(tab.current.hovered(), Some(h) if url == h.url()) {
Self::update_hovered(tab, op); Self::update_hovered(tab, op);
} else { } else {
Self::update_history(tab, op); Self::update_history(tab, op);
@ -73,7 +73,7 @@ impl Manager {
} }
fn update_current(tab: &mut Tab, op: Cow<FilesOp>, tasks: &Tasks) { fn update_current(tab: &mut Tab, op: Cow<FilesOp>, tasks: &Tasks) {
let hovered = tab.current.hovered().filter(|_| tab.current.tracing).map(|h| h.url()); let hovered = tab.current.hovered().filter(|_| tab.current.tracing).map(|h| h.url_owned());
let calc = !matches!(*op, FilesOp::Size(..) | FilesOp::Deleting(..)); let calc = !matches!(*op, FilesOp::Size(..) | FilesOp::Deleting(..));
let foreign = matches!(op, Cow::Borrowed(_)); let foreign = matches!(op, Cow::Borrowed(_));
@ -113,7 +113,7 @@ impl Manager {
); );
let folder = tab.history.entry(op.url().clone()).or_insert_with(|| Folder::from(op.url())); let folder = tab.history.entry(op.url().clone()).or_insert_with(|| Folder::from(op.url()));
let hovered = folder.hovered().filter(|_| folder.tracing).map(|h| h.url()); let hovered = folder.hovered().filter(|_| folder.tracing).map(|h| h.url_owned());
if folder.update(op.into_owned()) { if folder.update(op.into_owned()) {
folder.repos(hovered); folder.repos(hovered);
} }

View file

@ -46,11 +46,11 @@ impl Manager {
.current() .current()
.paginate(self.current().page) .paginate(self.current().page)
.iter() .iter()
.filter(|&f| updates.contains_key(&f.url)) .filter(|&f| updates.contains_key(f.url()))
.cloned() .cloned()
.collect(); .collect();
let repeek = self.hovered().is_some_and(|f| updates.contains_key(&f.url)); let repeek = self.hovered().is_some_and(|f| updates.contains_key(f.url()));
self.mimetype.extend(updates); self.mimetype.extend(updates);
if repeek { if repeek {

View file

@ -42,7 +42,7 @@ impl Yanked {
let (removal, addition) = match op { let (removal, addition) = match op {
FilesOp::Deleting(_, urls) => (urls.iter().collect(), vec![]), FilesOp::Deleting(_, urls) => (urls.iter().collect(), vec![]),
FilesOp::Updating(_, urls) | FilesOp::Upserting(_, urls) => { FilesOp::Updating(_, urls) | FilesOp::Upserting(_, urls) => {
urls.iter().filter(|(u, _)| self.contains(u)).map(|(u, f)| (u, f.url())).unzip() urls.iter().filter(|(u, _)| self.contains(u)).map(|(u, f)| (u, f.url_owned())).unzip()
} }
_ => (vec![], vec![]), _ => (vec![], vec![]),
}; };

View file

@ -4,6 +4,6 @@ use crate::tab::Tab;
impl Tab { impl Tab {
pub fn enter(&mut self, _: Cmd) { pub fn enter(&mut self, _: Cmd) {
self.current.hovered().filter(|h| h.is_dir()).map(|h| h.url()).map(|u| self.cd(u)); self.current.hovered().filter(|h| h.is_dir()).map(|h| h.url_owned()).map(|u| self.cd(u));
} }
} }

View file

@ -106,7 +106,7 @@ impl Tab {
render!(); render!();
let urls: Vec<_> = let urls: Vec<_> =
indices.into_iter().filter_map(|i| self.current.files.get(i)).map(|f| &f.url).collect(); indices.into_iter().filter_map(|i| self.current.files.get(i)).map(|f| f.url()).collect();
let same = !self.current.cwd.is_search(); let same = !self.current.cwd.is_search();
if !select { if !select {

View file

@ -65,13 +65,13 @@ impl Tab {
ManagerProxy::update_paged(); // Update for paged files in next loop ManagerProxy::update_paged(); // Update for paged files in next loop
} }
let hovered = self.current.hovered().map(|f| f.url()); let hovered = self.current.hovered().map(|f| f.url_owned());
if !self.current.files.set_filter(filter) { if !self.current.files.set_filter(filter) {
return; return;
} }
self.current.repos(hovered.as_ref()); self.current.repos(hovered.as_ref());
if self.current.hovered().map(|f| &f.url) != hovered.as_ref() { if self.current.hovered().map(|f| f.url()) != hovered.as_ref() {
ManagerProxy::hover(None, self.idx); ManagerProxy::hover(None, self.idx);
} }

View file

@ -11,10 +11,10 @@ impl Tab {
_ => !self.conf.show_hidden, _ => !self.conf.show_hidden,
}; };
let hovered = self.current.hovered().map(|f| f.url()); let hovered = self.current.hovered().map(|f| f.url_owned());
self.apply_files_attrs(); self.apply_files_attrs();
if hovered.as_ref() != self.current.hovered().map(|f| &f.url) { if hovered.as_ref() != self.current.hovered().map(|f| f.url()) {
ManagerProxy::hover(hovered, self.idx); ManagerProxy::hover(hovered, self.idx);
} else if self.current.hovered().is_some_and(|f| f.is_dir()) { } else if self.current.hovered().is_some_and(|f| f.is_dir()) {
ManagerProxy::peek(true); ManagerProxy::peek(true);

View file

@ -17,7 +17,7 @@ impl TryFrom<Cmd> for Opt {
impl Tab { impl Tab {
pub fn preview(&mut self, opt: impl TryInto<Opt>) { pub fn preview(&mut self, opt: impl TryInto<Opt>) {
let Some(hovered) = self.current.hovered().map(|h| &h.url) else { let Some(hovered) = self.current.hovered().map(|h| h.url()) else {
return render!(self.preview.reset()); return render!(self.preview.reset());
}; };

View file

@ -26,7 +26,7 @@ impl<'a> From<Cmd> for Opt<'a> {
impl<'a> Tab { impl<'a> Tab {
pub fn select(&mut self, opt: impl Into<Opt<'a>>) { pub fn select(&mut self, opt: impl Into<Opt<'a>>) {
let opt = opt.into() as Opt; let opt = opt.into() as Opt;
let Some(url) = opt.url.or_else(|| self.current.hovered().map(|h| Cow::Borrowed(&h.url))) let Some(url) = opt.url.or_else(|| self.current.hovered().map(|h| Cow::Borrowed(h.url())))
else { else {
return; return;
}; };

View file

@ -24,7 +24,7 @@ impl From<Option<bool>> for Opt {
impl Tab { impl Tab {
pub fn select_all(&mut self, opt: impl Into<Opt>) { pub fn select_all(&mut self, opt: impl Into<Opt>) {
let iter = self.current.files.iter().map(|f| &f.url); let iter = self.current.files.iter().map(|f| f.url());
let (removal, addition): (Vec<_>, Vec<_>) = match opt.into().state { let (removal, addition): (Vec<_>, Vec<_>) = match opt.into().state {
Some(true) => (vec![], iter.collect()), Some(true) => (vec![], iter.collect()),
Some(false) => (iter.collect(), vec![]), Some(false) => (iter.collect(), vec![]),

View file

@ -18,7 +18,7 @@ impl Finder {
pub(super) fn prev(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> { pub(super) fn prev(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> {
for i in !include as usize..files.len() { for i in !include as usize..files.len() {
let idx = (cursor + files.len() - i) % files.len(); let idx = (cursor + files.len() - i) % files.len();
if files[idx].name().is_some_and(|n| self.filter.matches(n)) { if self.filter.matches(files[idx].name()) {
return Some(idx as isize - cursor as isize); return Some(idx as isize - cursor as isize);
} }
} }
@ -28,7 +28,7 @@ impl Finder {
pub(super) fn next(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> { pub(super) fn next(&self, files: &Files, cursor: usize, include: bool) -> Option<isize> {
for i in !include as usize..files.len() { for i in !include as usize..files.len() {
let idx = (cursor + i) % files.len(); let idx = (cursor + i) % files.len();
if files[idx].name().is_some_and(|n| self.filter.matches(n)) { if self.filter.matches(files[idx].name()) {
return Some(idx as isize - cursor as isize); return Some(idx as isize - cursor as isize);
} }
} }
@ -43,11 +43,11 @@ impl Finder {
let mut i = 0u8; let mut i = 0u8;
for file in files.iter() { for file in files.iter() {
if file.name().map(|n| self.filter.matches(n)) != Some(true) { if !self.filter.matches(file.name()) {
continue; continue;
} }
self.matched.insert(file.url(), i); self.matched.insert(file.url_owned(), i);
if self.matched.len() > 99 { if self.matched.len() > 99 {
break; break;
} }

View file

@ -20,11 +20,11 @@ pub struct Preview {
impl Preview { impl Preview {
pub fn go(&mut self, file: File, mime: &str, force: bool) { pub fn go(&mut self, file: File, mime: &str, force: bool) {
if !force && self.content_unchanged(&file.url, file.cha) { if !force && self.content_unchanged(file.url(), file.cha) {
return; return;
} }
let Some(previewer) = PLUGIN.previewer(&file.url, mime) else { let Some(previewer) = PLUGIN.previewer(file.url(), mime) else {
self.reset(); self.reset();
return; return;
}; };
@ -38,7 +38,7 @@ impl Preview {
} }
pub fn go_folder(&mut self, file: File, dir: Option<Cha>, force: bool) { pub fn go_folder(&mut self, file: File, dir: Option<Cha>, force: bool) {
let (cha, url) = (file.cha, file.url()); let (cha, url) = (file.cha, file.url_owned());
self.go(file, MIME_DIR, force); self.go(file, MIME_DIR, force);
if self.content_unchanged(&url, cha) { if self.content_unchanged(&url, cha) {

View file

@ -106,7 +106,7 @@ impl Selected {
let (removal, addition) = match op { let (removal, addition) = match op {
FilesOp::Deleting(_, urls) => (urls.iter().collect(), vec![]), FilesOp::Deleting(_, urls) => (urls.iter().collect(), vec![]),
FilesOp::Updating(_, urls) | FilesOp::Upserting(_, urls) => { FilesOp::Updating(_, urls) | FilesOp::Upserting(_, urls) => {
urls.iter().filter(|&(u, _)| self.contains_key(u)).map(|(u, f)| (u, &f.url)).unzip() urls.iter().filter(|&(u, _)| self.contains_key(u)).map(|(u, f)| (u, f.url())).unzip()
} }
_ => (vec![], vec![]), _ => (vec![], vec![]),
}; };

View file

@ -39,7 +39,7 @@ impl Tab {
impl Tab { impl Tab {
// --- Current // --- Current
pub fn hovered_rect(&self) -> Option<Rect> { pub fn hovered_rect(&self) -> Option<Rect> {
let y = self.current.files.position(&self.current.hovered()?.url)? - self.current.offset; let y = self.current.files.position(self.current.hovered()?.url())? - self.current.offset;
let mut rect = LAYOUT.load().current; let mut rect = LAYOUT.load().current;
rect.y = rect.y.saturating_sub(1) + y as u16; rect.y = rect.y.saturating_sub(1) + y as u16;
@ -58,7 +58,7 @@ impl Tab {
pub fn selected_or_hovered(&self, reorder: bool) -> Box<dyn Iterator<Item = &Url> + '_> { pub fn selected_or_hovered(&self, reorder: bool) -> Box<dyn Iterator<Item = &Url> + '_> {
if self.selected.is_empty() { if self.selected.is_empty() {
Box::new(self.current.hovered().map(|h| vec![&h.url]).unwrap_or_default().into_iter()) Box::new(self.current.hovered().map(|h| vec![h.url()]).unwrap_or_default().into_iter())
} else if !reorder { } else if !reorder {
Box::new(self.selected.keys()) Box::new(self.selected.keys())
} else { } else {
@ -72,13 +72,13 @@ impl Tab {
let Some(h) = self.current.hovered() else { return Box::new(iter::empty()) }; let Some(h) = self.current.hovered() else { return Box::new(iter::empty()) };
if self.selected.is_empty() { if self.selected.is_empty() {
Box::new([&h.url, &h.url].into_iter()) Box::new([h.url(), h.url()].into_iter())
} else if !reorder { } else if !reorder {
Box::new([&h.url].into_iter().chain(self.selected.keys())) Box::new([h.url()].into_iter().chain(self.selected.keys()))
} else { } else {
let mut vec: Vec<_> = self.selected.iter().collect(); let mut vec: Vec<_> = self.selected.iter().collect();
vec.sort_unstable_by(|a, b| a.1.cmp(b.1)); vec.sort_unstable_by(|a, b| a.1.cmp(b.1));
Box::new([&h.url].into_iter().chain(vec.into_iter().map(|(k, _)| k))) Box::new([h.url()].into_iter().chain(vec.into_iter().map(|(k, _)| k)))
} }
} }
@ -90,7 +90,7 @@ impl Tab {
#[inline] #[inline]
pub fn hovered_folder(&self) -> Option<&Folder> { pub fn hovered_folder(&self) -> Option<&Folder> {
self.current.hovered().filter(|&h| h.is_dir()).and_then(|h| self.history.get(&h.url)) self.current.hovered().filter(|&h| h.is_dir()).and_then(|h| self.history.get(h.url()))
} }
pub fn apply_files_attrs(&mut self) { pub fn apply_files_attrs(&mut self) {
@ -99,7 +99,7 @@ impl Tab {
return render!(); return render!();
} }
let hovered = f.hovered().filter(|_| f.tracing).map(|h| h.url()); let hovered = f.hovered().filter(|_| f.tracing).map(|h| h.url_owned());
f.files.set_show_hidden(self.conf.show_hidden); f.files.set_show_hidden(self.conf.show_hidden);
f.files.set_sorter(self.conf.sorter()); f.files.set_sorter(self.conf.sorter());
@ -114,14 +114,14 @@ impl Tab {
// The parent should always track the CWD // The parent should always track the CWD
parent.hover(&self.current.cwd); parent.hover(&self.current.cwd);
parent.tracing = parent.hovered().map(|h| &h.url) == Some(&self.current.cwd); parent.tracing = parent.hovered().map(|h| h.url()) == Some(&self.current.cwd);
} }
self self
.current .current
.hovered() .hovered()
.filter(|h| h.is_dir()) .filter(|h| h.is_dir())
.and_then(|h| self.history.get_mut(&h.url)) .and_then(|h| self.history.get_mut(h.url()))
.map(apply); .map(apply);
} }
} }

View file

@ -12,17 +12,17 @@ impl Tasks {
let mut tasks: [Vec<_>; MAX_PREWORKERS as usize] = Default::default(); let mut tasks: [Vec<_>; MAX_PREWORKERS as usize] = Default::default();
for f in paged { for f in paged {
let mime = let mime =
if f.is_dir() { MIME_DIR } else { mimetype.get(&f.url).map(|s| &**s).unwrap_or_default() }; if f.is_dir() { MIME_DIR } else { mimetype.get(f.url()).map(|s| &**s).unwrap_or_default() };
let factors = |s: &str| match s { let factors = |s: &str| match s {
"mime" => !mime.is_empty(), "mime" => !mime.is_empty(),
_ => false, _ => false,
}; };
for p in PLUGIN.fetchers(&f.url, mime, factors) { for p in PLUGIN.fetchers(f.url(), mime, factors) {
match loaded.get_mut(&f.url) { match loaded.get_mut(f.url()) {
Some(n) if *n & (1 << p.idx) != 0 => continue, Some(n) if *n & (1 << p.idx) != 0 => continue,
Some(n) => *n |= 1 << p.idx, Some(n) => *n |= 1 << p.idx,
None => _ = loaded.insert(f.url.clone(), 1 << p.idx), None => _ = loaded.insert(f.url_owned(), 1 << p.idx),
} }
tasks[p.idx as usize].push(f.clone()); tasks[p.idx as usize].push(f.clone());
} }
@ -40,12 +40,12 @@ impl Tasks {
let mut loaded = self.scheduler.prework.loaded.lock(); let mut loaded = self.scheduler.prework.loaded.lock();
for f in paged { for f in paged {
let mime = let mime =
if f.is_dir() { MIME_DIR } else { mimetype.get(&f.url).map(|s| &**s).unwrap_or_default() }; if f.is_dir() { MIME_DIR } else { mimetype.get(f.url()).map(|s| &**s).unwrap_or_default() };
for p in PLUGIN.preloaders(&f.url, mime) { for p in PLUGIN.preloaders(f.url(), mime) {
match loaded.get_mut(&f.url) { match loaded.get_mut(f.url()) {
Some(n) if *n & (1 << p.idx) != 0 => continue, Some(n) if *n & (1 << p.idx) != 0 => continue,
Some(n) => *n |= 1 << p.idx, Some(n) => *n |= 1 << p.idx,
None => _ = loaded.insert(f.url.clone(), 1 << p.idx), None => _ = loaded.insert(f.url_owned(), 1 << p.idx),
} }
self.scheduler.preload_paged(p, f); self.scheduler.preload_paged(p, f);
} }
@ -57,7 +57,7 @@ impl Tasks {
{ {
let mut loaded = self.scheduler.prework.loaded.lock(); let mut loaded = self.scheduler.prework.loaded.lock();
for f in affected { for f in affected {
loaded.get_mut(&f.url).map(|n| *n &= mask); loaded.get_mut(f.url()).map(|n| *n &= mask);
} }
} }
@ -74,8 +74,10 @@ impl Tasks {
let loading = self.scheduler.prework.size_loading.read(); let loading = self.scheduler.prework.size_loading.read();
targets targets
.iter() .iter()
.filter(|f| f.is_dir() && !targets.sizes.contains_key(&f.url) && !loading.contains(&f.url)) .filter(|f| {
.map(|f| &f.url) f.is_dir() && !targets.sizes.contains_key(f.url()) && !loading.contains(f.url())
})
.map(|f| f.url())
.collect() .collect()
}; };
if targets.is_empty() { if targets.is_empty() {

View file

@ -39,18 +39,18 @@ impl File {
reg.add_field_method_get("idx", |_, me| Ok(me.idx + 1)); reg.add_field_method_get("idx", |_, me| Ok(me.idx + 1));
reg.add_method("size", |_, me, ()| { reg.add_method("size", |_, me, ()| {
Ok(if me.is_dir() { me.folder().files.sizes.get(&me.url).copied() } else { Some(me.len) }) Ok(if me.is_dir() { me.folder().files.sizes.get(me.url()).copied() } else { Some(me.len) })
}); });
reg.add_method("mime", |lua, me, ()| { reg.add_method("mime", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?; let cx = lua.named_registry_value::<CtxRef>("cx")?;
Ok(cx.manager.mimetype.get(&me.url).cloned()) Ok(cx.manager.mimetype.get(me.url()).cloned())
}); });
reg.add_method("prefix", |lua, me, ()| { reg.add_method("prefix", |lua, me, ()| {
if !me.folder().cwd.is_search() { if !me.folder().cwd.is_search() {
return Ok(None); return Ok(None);
} }
let mut p = me.url.strip_prefix(&me.folder().cwd).unwrap_or(&me.url).components(); let mut p = me.url().strip_prefix(&me.folder().cwd).unwrap_or(me.url()).components();
p.next_back(); p.next_back();
Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose() Some(lua.create_string(p.as_path().as_os_str().as_encoded_bytes())).transpose()
}); });
@ -59,7 +59,7 @@ impl File {
let mime = if me.is_dir() { let mime = if me.is_dir() {
MIME_DIR MIME_DIR
} else { } else {
cx.manager.mimetype.get(&me.url).map(|x| &**x).unwrap_or_default() cx.manager.mimetype.get(me.url()).map(|x| &**x).unwrap_or_default()
}; };
Ok(THEME.filetypes.iter().find(|&x| x.matches(me, mime)).map(|x| Style::from(x.style))) Ok(THEME.filetypes.iter().find(|&x| x.matches(me, mime)).map(|x| Style::from(x.style)))
@ -67,7 +67,7 @@ impl File {
reg.add_method("is_hovered", |_, me, ()| Ok(me.idx == me.folder().cursor)); reg.add_method("is_hovered", |_, me, ()| Ok(me.idx == me.folder().cursor));
reg.add_method("is_yanked", |lua, me, ()| { reg.add_method("is_yanked", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?; let cx = lua.named_registry_value::<CtxRef>("cx")?;
Ok(if !cx.manager.yanked.contains(&me.url) { Ok(if !cx.manager.yanked.contains(me.url()) {
0u8 0u8
} else if cx.manager.yanked.cut { } else if cx.manager.yanked.cut {
2u8 2u8
@ -87,13 +87,13 @@ impl File {
_ => 0u8, _ => 0u8,
}) })
}); });
reg.add_method("is_selected", |_, me, ()| Ok(me.tab().selected.contains_key(&me.url))); reg.add_method("is_selected", |_, me, ()| Ok(me.tab().selected.contains_key(me.url())));
reg.add_method("in_parent", |_, me, ()| { reg.add_method("in_parent", |_, me, ()| {
Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().cwd == f.cwd)) Ok(me.tab().parent.as_ref().is_some_and(|f| me.folder().cwd == f.cwd))
}); });
reg.add_method("in_current", |_, me, ()| Ok(me.folder().cwd == me.tab().current.cwd)); reg.add_method("in_current", |_, me, ()| Ok(me.folder().cwd == me.tab().current.cwd));
reg.add_method("in_preview", |_, me, ()| { reg.add_method("in_preview", |_, me, ()| {
Ok(me.tab().current.hovered().is_some_and(|f| me.folder().cwd == f.url)) Ok(me.tab().current.hovered().is_some_and(|f| me.folder().cwd == *f.url()))
}); });
reg.add_method("found", |lua, me, ()| { reg.add_method("found", |lua, me, ()| {
let cx = lua.named_registry_value::<CtxRef>("cx")?; let cx = lua.named_registry_value::<CtxRef>("cx")?;
@ -101,7 +101,7 @@ impl File {
return Ok(None); return Ok(None);
}; };
let Some(idx) = finder.matched_idx(&me.url) else { let Some(idx) = finder.matched_idx(me.url()) else {
return Ok(None); return Ok(None);
}; };
@ -116,7 +116,7 @@ impl File {
if me.folder().cwd != me.tab().current.cwd { if me.folder().cwd != me.tab().current.cwd {
return Ok(None); return Ok(None);
} }
let Some(h) = me.name().and_then(|n| finder.filter.highlighted(n)) else { let Some(h) = finder.filter.highlighted(me.name()) else {
return Ok(None); return Ok(None);
}; };

View file

@ -174,9 +174,9 @@ impl Files {
macro_rules! go { macro_rules! go {
($dist:expr, $src:expr, $inc:literal) => { ($dist:expr, $src:expr, $inc:literal) => {
let mut todo: HashMap<_, _> = $src.into_iter().map(|f| (f.url(), f)).collect(); let mut todo: HashMap<_, _> = $src.into_iter().map(|f| (f.url_owned(), f)).collect();
for f in &$dist { for f in &$dist {
if todo.remove(&f.url).is_some() && todo.is_empty() { if todo.remove(f.url()).is_some() && todo.is_empty() {
break; break;
} }
} }
@ -207,7 +207,7 @@ impl Files {
let mut todo: HashSet<_> = $src.into_iter().collect(); let mut todo: HashSet<_> = $src.into_iter().collect();
let len = $dist.len(); let len = $dist.len();
$dist.retain(|f| !todo.remove(&f.url)); $dist.retain(|f| !todo.remove(f.url()));
if $dist.len() != len { if $dist.len() != len {
self.revision += $inc; self.revision += $inc;
} }
@ -266,7 +266,7 @@ impl Files {
($dist:expr, $src:expr, $inc:literal) => { ($dist:expr, $src:expr, $inc:literal) => {
let mut b = true; let mut b = true;
for i in 0..$dist.len() { for i in 0..$dist.len() {
if let Some(f) = $src.remove(&$dist[i].url) { if let Some(f) = $src.remove($dist[i].url()) {
b &= $dist[i].cha.hits(f.cha); b &= $dist[i].cha.hits(f.cha);
$dist[i] = f; $dist[i] = f;
@ -282,7 +282,7 @@ impl Files {
let (mut hidden, mut items) = if let Some(filter) = &self.filter { let (mut hidden, mut items) = if let Some(filter) = &self.filter {
files.into_iter().partition(|(_, f)| { files.into_iter().partition(|(_, f)| {
(f.is_hidden() && !self.show_hidden) (f.is_hidden() && !self.show_hidden)
|| !f.url.file_name().is_some_and(|s| filter.matches(s)) || !f.url().file_name().is_some_and(|s| filter.matches(s))
}) })
} else if self.show_hidden { } else if self.show_hidden {
(HashMap::new(), files) (HashMap::new(), files)
@ -332,7 +332,7 @@ impl Files {
if let Some(filter) = &self.filter { if let Some(filter) = &self.filter {
files.into_iter().partition(|f| { files.into_iter().partition(|f| {
(f.is_hidden() && !self.show_hidden) (f.is_hidden() && !self.show_hidden)
|| !f.url.file_name().is_some_and(|s| filter.matches(s)) || !f.url().file_name().is_some_and(|s| filter.matches(s))
}) })
} else if self.show_hidden { } else if self.show_hidden {
(vec![], files.into_iter().collect()) (vec![], files.into_iter().collect())
@ -345,7 +345,8 @@ impl Files {
impl Files { impl Files {
// --- Items // --- Items
#[inline] #[inline]
pub fn position(&self, url: &Url) -> Option<usize> { self.iter().position(|f| f.url == *url) } // TODO: use `name` instead of `url`
pub fn position(&self, url: &Url) -> Option<usize> { self.iter().position(|f| url == f.url()) }
// --- Ticket // --- Ticket
#[inline] #[inline]

View file

@ -80,7 +80,7 @@ impl Folder {
} }
pub fn hover(&mut self, url: &Url) -> bool { pub fn hover(&mut self, url: &Url) -> bool {
if self.hovered().map(|h| &h.url) == Some(url) { if self.hovered().map(|h| h.url()) == Some(url) {
return false; return false;
} }

View file

@ -20,14 +20,10 @@ impl FilesSorter {
let by_alphabetical = |a: &File, b: &File| { let by_alphabetical = |a: &File, b: &File| {
if self.sensitive { if self.sensitive {
return self.cmp(&*a.url, &*b.url, self.promote(a, b)); return self.cmp(a.name(), b.name(), self.promote(a, b));
} }
self.cmp( self.cmp(a.name().to_ascii_uppercase(), b.name().to_ascii_uppercase(), self.promote(a, b))
a.url.as_os_str().to_ascii_uppercase(),
b.url.as_os_str().to_ascii_uppercase(),
self.promote(a, b),
)
}; };
match self.by { match self.by {
@ -42,11 +38,11 @@ impl FilesSorter {
}), }),
SortBy::Extension => items.sort_unstable_by(|a, b| { SortBy::Extension => items.sort_unstable_by(|a, b| {
let ord = if self.sensitive { let ord = if self.sensitive {
self.cmp(a.url.extension(), b.url.extension(), self.promote(a, b)) self.cmp(a.url().extension(), b.url().extension(), self.promote(a, b))
} else { } else {
self.cmp( self.cmp(
a.url.extension().map(|s| s.to_ascii_lowercase()), a.url().extension().map(|s| s.to_ascii_lowercase()),
b.url.extension().map(|s| s.to_ascii_lowercase()), b.url().extension().map(|s| s.to_ascii_lowercase()),
self.promote(a, b), self.promote(a, b),
) )
}; };
@ -55,8 +51,8 @@ impl FilesSorter {
SortBy::Alphabetical => items.sort_unstable_by(by_alphabetical), SortBy::Alphabetical => items.sort_unstable_by(by_alphabetical),
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| {
let aa = if a.is_dir() { sizes.get(&a.url).copied() } else { None }; 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 }; let bb = if b.is_dir() { sizes.get(b.url()).copied() } else { None };
let ord = self.cmp(aa.unwrap_or(a.len), bb.unwrap_or(b.len), self.promote(a, b)); let ord = self.cmp(aa.unwrap_or(a.len), bb.unwrap_or(b.len), self.promote(a, b));
if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord } if ord == Ordering::Equal { by_alphabetical(a, b) } else { ord }
}), }),
@ -79,16 +75,12 @@ impl FilesSorter {
let ordering = if self.translit { let ordering = if self.translit {
natsort( natsort(
a.url.as_os_str().as_encoded_bytes().transliterate().as_bytes(), a.name().as_encoded_bytes().transliterate().as_bytes(),
b.url.as_os_str().as_encoded_bytes().transliterate().as_bytes(), b.name().as_encoded_bytes().transliterate().as_bytes(),
!self.sensitive, !self.sensitive,
) )
} else { } else {
natsort( natsort(a.name().as_encoded_bytes(), b.name().as_encoded_bytes(), !self.sensitive)
a.url.as_os_str().as_encoded_bytes(),
b.url.as_os_str().as_encoded_bytes(),
!self.sensitive,
)
}; };
if self.reverse { ordering.reverse() } else { ordering } if self.reverse { ordering.reverse() } else { ordering }

View file

@ -18,14 +18,14 @@ impl File {
T: AsRef<yazi_shared::fs::File>, T: AsRef<yazi_shared::fs::File>,
{ {
reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.as_ref().cha)); reg.add_field_method_get("cha", |lua, me| Cha::cast(lua, me.as_ref().cha));
reg.add_field_method_get("url", |lua, me| Url::cast(lua, me.as_ref().url.clone())); reg.add_field_method_get("url", |lua, me| Url::cast(lua, me.as_ref().url_owned()));
reg.add_field_method_get("link_to", |lua, me| { reg.add_field_method_get("link_to", |lua, me| {
me.as_ref().link_to.clone().map(|u| Url::cast(lua, u)).transpose() me.as_ref().link_to.clone().map(|u| Url::cast(lua, u)).transpose()
}); });
// Extension // Extension
reg.add_field_method_get("name", |lua, me| { reg.add_field_method_get("name", |lua, me| {
me.as_ref().url.file_name().map(|n| lua.create_string(n.as_encoded_bytes())).transpose() me.as_ref().url().file_name().map(|n| lua.create_string(n.as_encoded_bytes())).transpose()
}); });
reg.add_method("icon", |lua, me, ()| { reg.add_method("icon", |lua, me, ()| {
@ -48,11 +48,14 @@ impl File {
lua.globals().raw_set( lua.globals().raw_set(
"File", "File",
lua.create_function(|lua, t: Table| { lua.create_function(|lua, t: Table| {
Self::cast(lua, yazi_shared::fs::File { // FIXME
cha: t.raw_get::<_, AnyUserData>("cha")?.take()?, todo!();
url: t.raw_get::<_, AnyUserData>("url")?.take()?, Ok(())
..Default::default() // Self::cast(lua, yazi_shared::fs::File {
}) // cha: t.raw_get::<_, AnyUserData>("cha")?.take()?,
// url: t.raw_get::<_, AnyUserData>("url")?.take()?,
// ..Default::default()
// })
})?, })?,
) )
} }

View file

@ -11,12 +11,12 @@ impl Utils {
"file_cache", "file_cache",
lua.create_function(|lua, t: Table| { lua.create_function(|lua, t: Table| {
let file: FileRef = t.raw_get("file")?; let file: FileRef = t.raw_get("file")?;
if file.url.parent() == Some(&PREVIEW.cache_dir) { if file.url().parent() == Some(&PREVIEW.cache_dir) {
return Ok(None); return Ok(None);
} }
let hex = { let hex = {
let mut digest = Md5::new_with_prefix(file.url.as_os_str().as_encoded_bytes()); let mut digest = Md5::new_with_prefix(file.url().as_os_str().as_encoded_bytes());
digest.update(format!("//{:?}//{}", file.cha.mtime, t.raw_get("skip").unwrap_or(0))); digest.update(format!("//{:?}//{}", file.cha.mtime, t.raw_get("skip").unwrap_or(0)));
format!("{:x}", digest.finalize()) format!("{:x}", digest.finalize())
}; };

View file

@ -21,7 +21,7 @@ impl<'a> TryFrom<Table<'a>> for PreviewLock {
let file: FileRef = t.raw_get("file")?; let file: FileRef = t.raw_get("file")?;
Ok(Self { Ok(Self {
cha: file.cha, cha: file.cha,
url: file.url(), url: file.url_owned(),
skip: t.raw_get("skip")?, skip: t.raw_get("skip")?,
window: t.raw_get("window")?, window: t.raw_get("window")?,
data: Default::default(), data: Default::default(),

View file

@ -30,7 +30,7 @@ impl Prework {
pub async fn work(&self, op: PreworkOp) -> Result<()> { pub async fn work(&self, op: PreworkOp) -> Result<()> {
match op { match op {
PreworkOp::Fetch(task) => { PreworkOp::Fetch(task) => {
let urls: Vec<_> = task.targets.iter().map(|f| f.url()).collect(); let urls: Vec<_> = task.targets.iter().map(|f| f.url_owned()).collect();
let result = isolate::fetch(&task.plugin.name, task.targets).await; let result = isolate::fetch(&task.plugin.name, task.targets).await;
if let Err(e) = result { if let Err(e) = result {
self.fail( self.fail(
@ -61,7 +61,7 @@ impl Prework {
self.prog.send(TaskProg::Adv(task.id, 1, 0))?; self.prog.send(TaskProg::Adv(task.id, 1, 0))?;
} }
PreworkOp::Load(task) => { PreworkOp::Load(task) => {
let url = task.target.url(); let url = task.target.url_owned();
let result = isolate::preload(&task.plugin.name, task.target).await; let result = isolate::preload(&task.plugin.name, task.target).await;
if let Err(e) = result { if let Err(e) = result {
self.fail( self.fail(

View file

@ -71,7 +71,7 @@ impl File {
impl File { impl File {
// --- Url // --- Url
#[inline] #[inline]
pub fn url(&self) -> Url { self.url.clone() } pub fn url_owned(&self) -> Url { self.url.clone() }
#[inline] #[inline]
pub fn name(&self) -> Option<&OsStr> { self.url.file_name() } pub fn name(&self) -> Option<&OsStr> { self.url.file_name() }

View file

@ -58,7 +58,9 @@ impl FilesOp {
.iter() .iter()
.map(|file| { .map(|file| {
let mut f = file.clone(); let mut f = file.clone();
f.url = new!(f.url); // FIXME
todo!();
// f.url = new!(f.url);
f f
}) })
.collect() .collect()
@ -70,7 +72,9 @@ impl FilesOp {
.iter() .iter()
.map(|(k, v)| { .map(|(k, v)| {
let mut f = v.clone(); let mut f = v.clone();
f.url = new!(f.url); // FIXME
todo!();
// f.url = new!(f.url);
(new!(k), f) (new!(k), f)
}) })
.collect() .collect()