mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
fa6e57d0ce
commit
f294881de6
4 changed files with 56 additions and 28 deletions
|
|
@ -105,7 +105,7 @@ impl Executor {
|
|||
if *cut {
|
||||
cx.tasks.file_cut(src, dest, force)
|
||||
} else {
|
||||
cx.tasks.file_copy(src, dest, force, exec.named.contains_key("follow"))
|
||||
cx.tasks.file_copy(src, dest, force)
|
||||
}
|
||||
}
|
||||
"link" => {
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@
|
|||
- paste: Paste the files.
|
||||
|
||||
- `--force`: Overwrite the destination file if it exists.
|
||||
- `--follow`: Copy the file pointed to by a symbolic link, rather than the link itself. Only valid during copying.
|
||||
|
||||
- remove: Move the files to the trash/recycle bin.
|
||||
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ impl Scheduler {
|
|||
});
|
||||
}
|
||||
|
||||
pub(super) fn file_copy(&self, from: Url, mut to: Url, force: bool, follow: bool) {
|
||||
pub(super) fn file_copy(&self, from: Url, mut to: Url, force: bool) {
|
||||
let name = format!("Copy {:?} to {:?}", from, to);
|
||||
let id = self.running.write().add(name);
|
||||
|
||||
|
|
@ -228,13 +228,13 @@ impl Scheduler {
|
|||
if !force {
|
||||
to = unique_path(to).await;
|
||||
}
|
||||
file.paste(FileOpPaste { id, from, to, cut: false, follow, retry: 0 }).await.ok();
|
||||
file.paste(FileOpPaste { id, from, to, cut: false, follow: true, retry: 0 }).await.ok();
|
||||
}
|
||||
.boxed()
|
||||
});
|
||||
}
|
||||
|
||||
pub(super) fn file_link(&self, from: Url, mut to: Url, force: bool) {
|
||||
pub(super) fn file_link(&self, from: Url, mut to: Url, force: bool, relative: bool) {
|
||||
let name = format!("Link {from:?} to {to:?}");
|
||||
let id = self.running.write().add(name);
|
||||
|
||||
|
|
@ -244,7 +244,10 @@ impl Scheduler {
|
|||
if !force {
|
||||
to = unique_path(to).await;
|
||||
}
|
||||
file.link(FileOpLink { id, from, to }).await.ok();
|
||||
file
|
||||
.link(FileOpLink { id, from, to, meta: None, resolve: false, relative, delete: false })
|
||||
.await
|
||||
.ok();
|
||||
}
|
||||
.boxed()
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use std::{collections::VecDeque, fs::Metadata, path::{Path, PathBuf}};
|
||||
use std::{borrow::Cow, collections::VecDeque, fs::Metadata, path::{Path, PathBuf}};
|
||||
|
||||
use anyhow::Result;
|
||||
use config::TASKS;
|
||||
use futures::{future::BoxFuture, FutureExt};
|
||||
use shared::{calculate_size, copy_with_progress, Url};
|
||||
use shared::{calculate_size, copy_with_progress, path_relative_to, Url};
|
||||
use tokio::{fs, io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc};
|
||||
use tracing::trace;
|
||||
|
||||
|
|
@ -36,11 +36,13 @@ pub(crate) struct FileOpPaste {
|
|||
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct FileOpLink {
|
||||
pub id: usize,
|
||||
pub from: Url,
|
||||
pub to: Url,
|
||||
pub cut: bool,
|
||||
pub length: u64,
|
||||
pub id: usize,
|
||||
pub from: Url,
|
||||
pub to: Url,
|
||||
pub meta: Option<Metadata>,
|
||||
pub resolve: bool,
|
||||
pub relative: bool,
|
||||
pub delete: bool,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -114,15 +116,23 @@ impl File {
|
|||
self.sch.send(TaskOp::Adv(task.id, 1, 0))?;
|
||||
}
|
||||
FileOp::Link(task) => {
|
||||
let src = match fs::read_link(&task.from).await {
|
||||
Ok(src) => src,
|
||||
Err(e) if e.kind() == NotFound => {
|
||||
self.log(task.id, format!("Link task partially done: {:?}", task))?;
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, task.length))?);
|
||||
let meta = task.meta.as_ref().unwrap();
|
||||
|
||||
let src = if task.resolve {
|
||||
match fs::read_link(&task.from).await {
|
||||
Ok(p) => Cow::Owned(p),
|
||||
Err(e) if e.kind() == NotFound => {
|
||||
self.log(task.id, format!("Link task partially done: {:?}", task))?;
|
||||
return Ok(self.sch.send(TaskOp::Adv(task.id, 1, meta.len()))?);
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
}
|
||||
Err(e) => Err(e)?,
|
||||
} else {
|
||||
Cow::Borrowed(task.from.as_path())
|
||||
};
|
||||
|
||||
let src = if task.relative { path_relative_to(&src, &task.to) } else { src };
|
||||
|
||||
match fs::remove_file(&task.to).await {
|
||||
Err(e) if e.kind() != NotFound => Err(e)?,
|
||||
_ => {
|
||||
|
|
@ -132,15 +142,19 @@ impl File {
|
|||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
fs::symlink_file(src, &task.to).await?
|
||||
if meta.is_dir() {
|
||||
fs::symlink_dir(src, &task.to).await?
|
||||
} else {
|
||||
fs::symlink_file(src, &task.to).await?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if task.cut {
|
||||
if task.delete {
|
||||
fs::remove_file(&task.from).await.ok();
|
||||
}
|
||||
self.sch.send(TaskOp::Adv(task.id, 1, task.length))?;
|
||||
self.sch.send(TaskOp::Adv(task.id, 1, meta.len()))?;
|
||||
}
|
||||
FileOp::Delete(task) => {
|
||||
if let Err(e) = fs::remove_file(&task.target).await {
|
||||
|
|
@ -192,7 +206,7 @@ impl File {
|
|||
if meta.is_file() {
|
||||
self.tx.send(FileOp::Paste(task)).await?;
|
||||
} else if meta.is_symlink() {
|
||||
self.tx.send(FileOp::Link(task.to_link(meta.len()))).await?;
|
||||
self.tx.send(FileOp::Link(task.to_link(meta))).await?;
|
||||
}
|
||||
return self.done(id);
|
||||
}
|
||||
|
|
@ -237,16 +251,20 @@ impl File {
|
|||
if meta.is_file() {
|
||||
self.tx.send(FileOp::Paste(task.clone())).await?;
|
||||
} else if meta.is_symlink() {
|
||||
self.tx.send(FileOp::Link(task.to_link(meta.len()))).await?;
|
||||
self.tx.send(FileOp::Link(task.to_link(meta))).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
self.done(task.id)
|
||||
}
|
||||
|
||||
pub(crate) async fn link(&self, task: FileOpLink) -> Result<()> {
|
||||
pub(crate) async fn link(&self, mut task: FileOpLink) -> Result<()> {
|
||||
let id = task.id;
|
||||
self.sch.send(TaskOp::New(id, 0))?;
|
||||
if task.meta.is_none() {
|
||||
task.meta = Some(fs::symlink_metadata(&task.from).await?);
|
||||
}
|
||||
|
||||
self.sch.send(TaskOp::New(id, task.meta.as_ref().unwrap().len()))?;
|
||||
self.tx.send(FileOp::Link(task)).await?;
|
||||
self.done(id)
|
||||
}
|
||||
|
|
@ -328,7 +346,15 @@ impl File {
|
|||
}
|
||||
|
||||
impl FileOpPaste {
|
||||
fn to_link(&self, length: u64) -> FileOpLink {
|
||||
FileOpLink { id: self.id, from: self.from.clone(), to: self.to.clone(), cut: self.cut, length }
|
||||
fn to_link(&self, meta: Metadata) -> FileOpLink {
|
||||
FileOpLink {
|
||||
id: self.id,
|
||||
from: self.from.clone(),
|
||||
to: self.to.clone(),
|
||||
meta: Some(meta),
|
||||
resolve: true,
|
||||
relative: false,
|
||||
delete: self.cut,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue