mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-21 23:01:05 +00:00
fix: make every effort to carry hidden states for dummy files (#2814)
This commit is contained in:
parent
4076e35a2f
commit
4fdc0f120f
22 changed files with 175 additions and 165 deletions
|
|
@ -94,7 +94,7 @@ impl Mgr {
|
|||
failed.push((o, n, anyhow!("Destination already exists")));
|
||||
} else if let Err(e) = fs::rename(&old, &new).await {
|
||||
failed.push((o, n, e.into()));
|
||||
} else if let Ok(f) = File::from(new.into()).await {
|
||||
} else if let Ok(f) = File::new(new.into()).await {
|
||||
succeeded.insert(Url::from(old), f);
|
||||
} else {
|
||||
failed.push((o, n, anyhow!("Failed to retrieve file info")));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
use anyhow::Result;
|
||||
use tokio::fs;
|
||||
use yazi_config::popup::{ConfirmCfg, InputCfg};
|
||||
|
|
@ -50,7 +48,7 @@ impl Mgr {
|
|||
fs::create_dir_all(&new).await?;
|
||||
} else if let Some(real) = realname(&new).await {
|
||||
ok_or_not_found(fs::remove_file(&new).await)?;
|
||||
FilesOp::Deleting(parent.clone(), HashSet::from_iter([UrnBuf::from(real)])).emit();
|
||||
FilesOp::Deleting(parent.clone(), [UrnBuf::from(real)].into()).emit();
|
||||
fs::File::create(&new).await?;
|
||||
} else {
|
||||
fs::create_dir_all(&parent).await.ok();
|
||||
|
|
@ -58,8 +56,8 @@ impl Mgr {
|
|||
fs::File::create(&new).await?;
|
||||
}
|
||||
|
||||
if let Ok(f) = File::from(new.clone()).await {
|
||||
FilesOp::Upserting(parent, HashMap::from_iter([(f.urn_owned(), f)])).emit();
|
||||
if let Ok(f) = File::new(new.clone()).await {
|
||||
FilesOp::Upserting(parent, [(f.urn_owned(), f)].into()).emit();
|
||||
TabProxy::reveal(&new)
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ impl Mgr {
|
|||
tokio::spawn(async move {
|
||||
let mut files = Vec::with_capacity(todo.len());
|
||||
for u in todo {
|
||||
if let Ok(f) = File::from(u).await {
|
||||
if let Ok(f) = File::new(u).await {
|
||||
files.push(f);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use std::{borrow::Cow, collections::{HashMap, HashSet}};
|
||||
use std::borrow::Cow;
|
||||
|
||||
use anyhow::Result;
|
||||
use tokio::fs;
|
||||
|
|
@ -80,15 +80,15 @@ impl Mgr {
|
|||
|
||||
if let Some(o) = overwritten {
|
||||
ok_or_not_found(fs::rename(p_new.join(&o), &new).await)?;
|
||||
FilesOp::Deleting(p_new.clone(), HashSet::from_iter([UrnBuf::from(o)])).emit();
|
||||
FilesOp::Deleting(p_new.clone(), [UrnBuf::from(o)].into()).emit();
|
||||
}
|
||||
|
||||
let file = File::from(new.clone()).await?;
|
||||
let file = File::new(new.clone()).await?;
|
||||
if p_new == p_old {
|
||||
FilesOp::Upserting(p_old, HashMap::from_iter([(n_old, file)])).emit();
|
||||
FilesOp::Upserting(p_old, [(n_old, file)].into()).emit();
|
||||
} else {
|
||||
FilesOp::Deleting(p_old, HashSet::from_iter([n_old])).emit();
|
||||
FilesOp::Upserting(p_new, HashMap::from_iter([(n_new, file)])).emit();
|
||||
FilesOp::Deleting(p_old, [n_old].into()).emit();
|
||||
FilesOp::Upserting(p_new, [(n_new, file)].into()).emit();
|
||||
}
|
||||
|
||||
TabProxy::reveal(&new);
|
||||
|
|
|
|||
|
|
@ -134,8 +134,8 @@ impl Watcher {
|
|||
|
||||
for u in urls {
|
||||
let Some((parent, urn)) = u.pair() else { continue };
|
||||
let Ok(file) = File::from(u).await else {
|
||||
ops.push(FilesOp::Deleting(parent, HashSet::from_iter([urn])));
|
||||
let Ok(file) = File::new(u).await else {
|
||||
ops.push(FilesOp::Deleting(parent, [urn].into()));
|
||||
continue;
|
||||
};
|
||||
|
||||
|
|
@ -144,11 +144,11 @@ impl Watcher {
|
|||
|| realname_unchecked(u, &mut cached).await.is_ok_and(|s| urn.as_urn() == s);
|
||||
|
||||
if !eq {
|
||||
ops.push(FilesOp::Deleting(parent, HashSet::from_iter([urn])));
|
||||
ops.push(FilesOp::Deleting(parent, [urn].into()));
|
||||
continue;
|
||||
}
|
||||
|
||||
ops.push(FilesOp::Upserting(parent, HashMap::from_iter([(urn, file)])));
|
||||
ops.push(FilesOp::Upserting(parent, [(urn, file)].into()));
|
||||
}
|
||||
|
||||
FilesOp::mutate(ops);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use std::{mem, time::Duration};
|
||||
|
||||
use tokio::{fs, pin};
|
||||
use tokio::pin;
|
||||
use tokio_stream::{StreamExt, wrappers::UnboundedReceiverStream};
|
||||
use yazi_config::popup::InputCfg;
|
||||
use yazi_dds::Pubsub;
|
||||
use yazi_fs::expand_path;
|
||||
use yazi_fs::{File, FilesOp, expand_path};
|
||||
use yazi_macro::render;
|
||||
use yazi_proxy::{CmpProxy, InputProxy, MgrProxy, TabProxy};
|
||||
use yazi_shared::{Debounce, errors::InputError, event::CmdCow, url::Url};
|
||||
|
|
@ -94,16 +94,17 @@ impl Tab {
|
|||
while let Some(result) = rx.next().await {
|
||||
match result {
|
||||
Ok(s) => {
|
||||
let u = Url::from(expand_path(s));
|
||||
let Ok(meta) = fs::metadata(&u).await else {
|
||||
return;
|
||||
};
|
||||
let url = Url::from(expand_path(s));
|
||||
|
||||
if meta.is_dir() {
|
||||
TabProxy::cd(&u);
|
||||
} else {
|
||||
TabProxy::reveal(&u);
|
||||
let Ok(file) = File::new(url.clone()).await else { return };
|
||||
if file.is_dir() {
|
||||
return TabProxy::cd(&url);
|
||||
}
|
||||
|
||||
if let Some(p) = url.parent_url() {
|
||||
FilesOp::Upserting(p, [(url.urn_owned(), file)].into()).emit();
|
||||
}
|
||||
TabProxy::reveal(&url);
|
||||
}
|
||||
Err(InputError::Completed(before, ticket)) => {
|
||||
CmpProxy::trigger(&before, ticket);
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl Tab {
|
|||
while let Some(chunk) = rx.next().await {
|
||||
FilesOp::Part(cwd.clone(), chunk, ticket).emit();
|
||||
}
|
||||
FilesOp::Done(cwd, Cha::dummy(), ticket).emit();
|
||||
FilesOp::Done(cwd, Cha::default(), ticket).emit();
|
||||
|
||||
Ok(())
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ impl Folder {
|
|||
(self.cha, self.stage) = (cha, FolderStage::Loaded);
|
||||
}
|
||||
FilesOp::Part(_, ref files, _) if files.is_empty() => {
|
||||
(self.cha, self.stage) = (Cha::dummy(), FolderStage::Loading);
|
||||
(self.cha, self.stage) = (Cha::default(), FolderStage::Loading);
|
||||
}
|
||||
FilesOp::Part(_, _, ticket) if ticket == self.files.ticket() => {
|
||||
self.stage = FolderStage::Loading;
|
||||
|
|
@ -55,7 +55,7 @@ impl Folder {
|
|||
(self.cha, self.stage) = (cha, FolderStage::Loaded);
|
||||
}
|
||||
FilesOp::IOErr(_, kind) => {
|
||||
(self.cha, self.stage) = (Cha::dummy(), FolderStage::Failed(kind));
|
||||
(self.cha, self.stage) = (Cha::default(), FolderStage::Failed(kind));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ impl Preview {
|
|||
Some(PreviewLock { url: wd.clone(), cha, mime: MIME_DIR.to_owned(), ..Default::default() });
|
||||
self.folder_loader.take().map(|h| h.abort());
|
||||
self.folder_loader = Some(tokio::spawn(async move {
|
||||
let Some(new) = Files::assert_stale(&wd, dir.unwrap_or(Cha::dummy())).await else { return };
|
||||
let Some(new) = Files::assert_stale(&wd, dir.unwrap_or_default()).await else { return };
|
||||
|
||||
let rx = match Files::from_dir(&wd).await {
|
||||
Ok(rx) => rx,
|
||||
|
|
|
|||
|
|
@ -1,10 +1,12 @@
|
|||
use std::{fs::{FileType, Metadata}, path::Path, time::SystemTime};
|
||||
|
||||
use tokio::fs;
|
||||
use yazi_macro::{unix_either, win_either};
|
||||
use yazi_shared::url::Url;
|
||||
|
||||
use super::ChaKind;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Cha {
|
||||
pub kind: ChaKind,
|
||||
pub len: u64,
|
||||
|
|
@ -25,8 +27,110 @@ pub struct Cha {
|
|||
pub nlink: libc::nlink_t,
|
||||
}
|
||||
|
||||
impl From<&Metadata> for Cha {
|
||||
fn from(m: &Metadata) -> Self {
|
||||
impl Default for Cha {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
kind: ChaKind::DUMMY,
|
||||
len: 0,
|
||||
atime: None,
|
||||
btime: None,
|
||||
#[cfg(unix)]
|
||||
ctime: None,
|
||||
mtime: None,
|
||||
#[cfg(unix)]
|
||||
mode: 0,
|
||||
#[cfg(unix)]
|
||||
dev: 0,
|
||||
#[cfg(unix)]
|
||||
uid: 0,
|
||||
#[cfg(unix)]
|
||||
gid: 0,
|
||||
#[cfg(unix)]
|
||||
nlink: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cha {
|
||||
#[inline]
|
||||
pub fn new(path: &Path, meta: Metadata) -> Self {
|
||||
Self::from_just_meta(&meta).attach(ChaKind::hidden(path, &meta))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn from_url(url: &Url) -> std::io::Result<Self> {
|
||||
Ok(Self::from_follow(url, fs::symlink_metadata(url).await?).await)
|
||||
}
|
||||
|
||||
pub async fn from_follow(path: &Path, mut meta: Metadata) -> Self {
|
||||
let mut attached = ChaKind::hidden(path, &meta);
|
||||
if meta.is_symlink() {
|
||||
attached |= ChaKind::LINK;
|
||||
meta = fs::metadata(path).await.unwrap_or(meta);
|
||||
}
|
||||
if meta.is_symlink() {
|
||||
attached |= ChaKind::ORPHAN;
|
||||
}
|
||||
|
||||
Self::from_just_meta(&meta).attach(attached)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_dummy(url: &Url, ft: Option<FileType>) -> Self {
|
||||
let mut me = ft.map(Self::from_half_ft).unwrap_or_default();
|
||||
#[cfg(unix)]
|
||||
if yazi_shared::url::Urn::new(url).is_hidden() {
|
||||
me.kind |= ChaKind::HIDDEN;
|
||||
}
|
||||
me
|
||||
}
|
||||
|
||||
fn from_half_ft(ft: FileType) -> Self {
|
||||
let mut kind = ChaKind::DUMMY;
|
||||
|
||||
#[cfg(unix)]
|
||||
let mode = {
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
if ft.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
libc::S_IFDIR
|
||||
} else if ft.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
libc::S_IFLNK
|
||||
} else if ft.is_block_device() {
|
||||
libc::S_IFBLK
|
||||
} else if ft.is_char_device() {
|
||||
libc::S_IFCHR
|
||||
} else if ft.is_fifo() {
|
||||
libc::S_IFIFO
|
||||
} else if ft.is_socket() {
|
||||
libc::S_IFSOCK
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if ft.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
} else if ft.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
kind,
|
||||
#[cfg(unix)]
|
||||
mode,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
fn from_just_meta(m: &Metadata) -> Self {
|
||||
#[cfg(unix)]
|
||||
use std::{os::unix::{fs::MetadataExt, prelude::PermissionsExt}, time::{Duration, UNIX_EPOCH}};
|
||||
|
||||
let mut kind = ChaKind::empty();
|
||||
if m.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
|
|
@ -40,115 +144,20 @@ impl From<&Metadata> for Cha {
|
|||
atime: m.accessed().ok(),
|
||||
btime: m.created().ok(),
|
||||
#[cfg(unix)]
|
||||
ctime: {
|
||||
use std::{os::unix::fs::MetadataExt, time::{Duration, UNIX_EPOCH}};
|
||||
UNIX_EPOCH.checked_add(Duration::new(m.ctime() as u64, m.ctime_nsec() as u32))
|
||||
},
|
||||
ctime: UNIX_EPOCH.checked_add(Duration::new(m.ctime() as u64, m.ctime_nsec() as u32)),
|
||||
mtime: m.modified().ok(),
|
||||
|
||||
#[cfg(unix)]
|
||||
mode: {
|
||||
use std::os::unix::prelude::PermissionsExt;
|
||||
m.permissions().mode() as _
|
||||
},
|
||||
mode: m.permissions().mode() as _,
|
||||
#[cfg(unix)]
|
||||
dev: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.dev() as _
|
||||
},
|
||||
dev: m.dev() as _,
|
||||
#[cfg(unix)]
|
||||
uid: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.uid() as _
|
||||
},
|
||||
uid: m.uid() as _,
|
||||
#[cfg(unix)]
|
||||
gid: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.gid() as _
|
||||
},
|
||||
gid: m.gid() as _,
|
||||
#[cfg(unix)]
|
||||
nlink: {
|
||||
use std::os::unix::fs::MetadataExt;
|
||||
m.nlink() as _
|
||||
},
|
||||
nlink: m.nlink() as _,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Metadata> for Cha {
|
||||
fn from(m: Metadata) -> Self { Self::from(&m) }
|
||||
}
|
||||
|
||||
impl From<FileType> for Cha {
|
||||
fn from(t: FileType) -> Self {
|
||||
let mut kind = ChaKind::DUMMY;
|
||||
|
||||
#[cfg(unix)]
|
||||
let mode = {
|
||||
use std::os::unix::fs::FileTypeExt;
|
||||
if t.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
libc::S_IFDIR
|
||||
} else if t.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
libc::S_IFLNK
|
||||
} else if t.is_block_device() {
|
||||
libc::S_IFBLK
|
||||
} else if t.is_char_device() {
|
||||
libc::S_IFCHR
|
||||
} else if t.is_fifo() {
|
||||
libc::S_IFIFO
|
||||
} else if t.is_socket() {
|
||||
libc::S_IFSOCK
|
||||
} else {
|
||||
0
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(windows)]
|
||||
{
|
||||
if t.is_dir() {
|
||||
kind |= ChaKind::DIR;
|
||||
} else if t.is_symlink() {
|
||||
kind |= ChaKind::LINK;
|
||||
}
|
||||
}
|
||||
|
||||
Self {
|
||||
kind,
|
||||
#[cfg(unix)]
|
||||
mode,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Cha {
|
||||
pub async fn new(path: &Path, mut meta: Metadata) -> Self {
|
||||
let mut attached = ChaKind::hidden(path, &meta);
|
||||
|
||||
if meta.is_symlink() {
|
||||
attached |= ChaKind::LINK;
|
||||
meta = tokio::fs::metadata(path).await.unwrap_or(meta);
|
||||
}
|
||||
if meta.is_symlink() {
|
||||
attached |= ChaKind::ORPHAN;
|
||||
}
|
||||
|
||||
let mut me = Self::from(meta);
|
||||
me.kind |= attached;
|
||||
me
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn new_nofollow(_path: &Path, meta: Metadata) -> Self {
|
||||
let mut me = Self::from(&meta);
|
||||
me.kind |= ChaKind::hidden(_path, &meta);
|
||||
me
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn dummy() -> Self { Self { kind: ChaKind::DUMMY, ..Default::default() } }
|
||||
|
||||
#[inline]
|
||||
pub fn hits(self, c: Self) -> bool {
|
||||
|
|
@ -159,6 +168,12 @@ impl Cha {
|
|||
&& self.kind == c.kind
|
||||
&& unix_either!(self.mode == c.mode, true)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn attach(mut self, kind: ChaKind) -> Self {
|
||||
self.kind |= kind;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Cha {
|
||||
|
|
|
|||
|
|
@ -23,29 +23,25 @@ impl Deref for File {
|
|||
|
||||
impl File {
|
||||
#[inline]
|
||||
pub async fn from(url: Url) -> Result<Self> {
|
||||
pub async fn new(url: Url) -> Result<Self> {
|
||||
let meta = fs::symlink_metadata(&url).await?;
|
||||
Ok(Self::from_meta(url, meta).await)
|
||||
Ok(Self::from_follow(url, meta).await)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub async fn from_meta(url: Url, meta: Metadata) -> Self {
|
||||
pub async fn from_follow(url: Url, meta: Metadata) -> Self {
|
||||
let link_to =
|
||||
if meta.is_symlink() { fs::read_link(&url).await.map(Url::from).ok() } else { None };
|
||||
|
||||
let cha = Cha::new(&url, meta).await;
|
||||
let cha = Cha::from_follow(&url, meta).await;
|
||||
|
||||
Self { url, cha, link_to, icon: Default::default() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_dummy(url: Url, ft: Option<FileType>) -> Self {
|
||||
Self {
|
||||
url,
|
||||
cha: ft.map_or_else(Cha::dummy, Cha::from),
|
||||
link_to: None,
|
||||
icon: Default::default(),
|
||||
}
|
||||
let cha = Cha::from_dummy(&url, ft);
|
||||
Self { url, cha, link_to: None, icon: Default::default() }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ impl Files {
|
|||
result = item.metadata() => {
|
||||
let url = Url::from(item.path());
|
||||
_ = tx.send(match result {
|
||||
Ok(meta) => File::from_meta(url, meta).await,
|
||||
Ok(meta) => File::from_follow(url, meta).await,
|
||||
Err(_) => File::from_dummy(url, item.file_type().await.ok())
|
||||
});
|
||||
}
|
||||
|
|
@ -65,7 +65,7 @@ impl Files {
|
|||
for entry in entries {
|
||||
let url = Url::from(entry.path());
|
||||
files.push(match entry.metadata().await {
|
||||
Ok(meta) => File::from_meta(url, meta).await,
|
||||
Ok(meta) => File::from_follow(url, meta).await,
|
||||
Err(_) => File::from_dummy(url, entry.file_type().await.ok()),
|
||||
});
|
||||
}
|
||||
|
|
@ -83,7 +83,7 @@ impl Files {
|
|||
|
||||
pub async fn assert_stale(dir: &Url, cha: Cha) -> Option<Cha> {
|
||||
use std::io::ErrorKind;
|
||||
match fs::metadata(dir).await.map(Cha::from) {
|
||||
match Cha::from_url(dir).await {
|
||||
Ok(c) if !c.is_dir() => FilesOp::issue_error(dir, ErrorKind::NotADirectory).await,
|
||||
Ok(c) if c.hits(cha) && PARTITIONS.read().heuristic(cha) => {}
|
||||
Ok(c) => return Some(c),
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ impl FilesOp {
|
|||
} else if maybe_exists(cwd).await {
|
||||
Self::IOErr(cwd.clone(), kind).emit();
|
||||
} else if let Some((p, n)) = cwd.pair() {
|
||||
Self::Deleting(p, HashSet::from_iter([n])).emit();
|
||||
Self::Deleting(p, [n].into()).emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use mlua::{ExternalError, FromLua, IntoLua, Lua, Table, UserData, UserDataFields
|
|||
use yazi_fs::cha::ChaKind;
|
||||
|
||||
#[derive(Clone, Copy, FromLua)]
|
||||
pub struct Cha(yazi_fs::cha::Cha);
|
||||
pub struct Cha(pub yazi_fs::cha::Cha);
|
||||
|
||||
impl Deref for Cha {
|
||||
type Target = yazi_fs::cha::Cha;
|
||||
|
|
@ -12,10 +12,6 @@ impl Deref for Cha {
|
|||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
impl<T: Into<yazi_fs::cha::Cha>> From<T> for Cha {
|
||||
fn from(cha: T) -> Self { Self(cha.into()) }
|
||||
}
|
||||
|
||||
impl Cha {
|
||||
pub fn install(lua: &Lua) -> mlua::Result<()> {
|
||||
#[inline]
|
||||
|
|
@ -33,7 +29,7 @@ impl Cha {
|
|||
let kind =
|
||||
ChaKind::from_bits(t.raw_get("kind")?).ok_or_else(|| "Invalid kind".into_lua_err())?;
|
||||
|
||||
Self::from(yazi_fs::cha::Cha {
|
||||
Self(yazi_fs::cha::Cha {
|
||||
kind,
|
||||
len: t.raw_get("len").unwrap_or_default(),
|
||||
atime: parse_time(t.raw_get("atime").ok())?,
|
||||
|
|
|
|||
2
yazi-plugin/src/external/fd.rs
vendored
2
yazi-plugin/src/external/fd.rs
vendored
|
|
@ -20,7 +20,7 @@ pub fn fd(opt: FdOpt) -> Result<UnboundedReceiver<File>> {
|
|||
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(line)) = it.next_line().await {
|
||||
if let Ok(file) = File::from(opt.cwd.join(line)).await {
|
||||
if let Ok(file) = File::new(opt.cwd.join(line)).await {
|
||||
tx.send(file).ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
yazi-plugin/src/external/rg.rs
vendored
2
yazi-plugin/src/external/rg.rs
vendored
|
|
@ -29,7 +29,7 @@ pub fn rg(opt: RgOpt) -> Result<UnboundedReceiver<File>> {
|
|||
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(line)) = it.next_line().await {
|
||||
if let Ok(file) = File::from(opt.cwd.join(line)).await {
|
||||
if let Ok(file) = File::new(opt.cwd.join(line)).await {
|
||||
tx.send(file).ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
yazi-plugin/src/external/rga.rs
vendored
2
yazi-plugin/src/external/rga.rs
vendored
|
|
@ -29,7 +29,7 @@ pub fn rga(opt: RgaOpt) -> Result<UnboundedReceiver<File>> {
|
|||
|
||||
tokio::spawn(async move {
|
||||
while let Ok(Some(line)) = it.next_line().await {
|
||||
if let Ok(file) = File::from(opt.cwd.join(line)).await {
|
||||
if let Ok(file) = File::new(opt.cwd.join(line)).await {
|
||||
tx.send(file).ok();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ fn cha(lua: &Lua) -> mlua::Result<Function> {
|
|||
};
|
||||
|
||||
match meta {
|
||||
Ok(m) => Cha::from(m).into_lua_multi(&lua),
|
||||
Ok(m) => Cha(yazi_fs::cha::Cha::new(&url, m)).into_lua_multi(&lua),
|
||||
Err(e) => (Value::Nil, Error::Io(e)).into_lua_multi(&lua),
|
||||
}
|
||||
})
|
||||
|
|
@ -138,7 +138,7 @@ fn read_dir(lua: &Lua) -> mlua::Result<Function> {
|
|||
let file = if !resolve {
|
||||
yazi_fs::File::from_dummy(url, next.file_type().await.ok())
|
||||
} else if let Ok(meta) = next.metadata().await {
|
||||
yazi_fs::File::from_meta(url, meta).await
|
||||
yazi_fs::File::from_follow(url, meta).await
|
||||
} else {
|
||||
yazi_fs::File::from_dummy(url, next.file_type().await.ok())
|
||||
};
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ macro_rules! impl_style_shorthands {
|
|||
#[macro_export]
|
||||
macro_rules! impl_file_fields {
|
||||
($fields:ident) => {
|
||||
yazi_binding::cached_field!($fields, cha, |_, me| Ok($crate::bindings::Cha::from(me.cha)));
|
||||
yazi_binding::cached_field!($fields, cha, |_, me| Ok($crate::bindings::Cha(me.cha)));
|
||||
yazi_binding::cached_field!($fields, url, |_, me| Ok(yazi_binding::Url::new(me.url_owned())));
|
||||
yazi_binding::cached_field!($fields, link_to, |_, me| Ok(
|
||||
me.link_to.clone().map(yazi_binding::Url::new)
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ impl TabProxy {
|
|||
|
||||
#[inline]
|
||||
pub fn reveal(target: &Url) {
|
||||
emit!(Call(Cmd::args("mgr:reveal", &[target])));
|
||||
emit!(Call(Cmd::args("mgr:reveal", &[target]).with("no-dummy", true)));
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -328,15 +328,15 @@ impl File {
|
|||
#[inline]
|
||||
async fn cha(path: &Path, follow: bool) -> io::Result<Cha> {
|
||||
let meta = fs::symlink_metadata(path).await?;
|
||||
Ok(if follow { Cha::new(path, meta).await } else { Cha::new_nofollow(path, meta) })
|
||||
Ok(if follow { Cha::from_follow(path, meta).await } else { Cha::new(path, meta) })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
async fn cha_from(entry: DirEntry, path: &Path, follow: bool) -> io::Result<Cha> {
|
||||
Ok(if follow {
|
||||
Cha::new(path, entry.metadata().await?).await
|
||||
Cha::from_follow(path, entry.metadata().await?).await
|
||||
} else {
|
||||
Cha::new_nofollow(path, entry.metadata().await?)
|
||||
Cha::new(path, entry.metadata().await?)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,10 @@ impl Data {
|
|||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Data {
|
||||
fn from(value: bool) -> Self { Self::Boolean(value) }
|
||||
}
|
||||
|
||||
impl From<usize> for Data {
|
||||
fn from(value: usize) -> Self { Self::Id(value.into()) }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue