Skip to content

Commit

Permalink
Add '--hard' option to 'link' command
Browse files Browse the repository at this point in the history
Resolves #1258.
  • Loading branch information
Ape committed Jul 6, 2024
1 parent 11547ee commit a90cb1c
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions yazi-core/src/manager/commands/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ use crate::{manager::Manager, tasks::Tasks};

pub struct Opt {
relative: bool,
hard: bool,
force: bool,
}

impl From<Cmd> for Opt {
fn from(c: Cmd) -> Self { Self { relative: c.bool("relative"), force: c.bool("force") } }
fn from(c: Cmd) -> Self {
Self { relative: c.bool("relative"), hard: c.bool("hard"), force: c.bool("force") }
}
}

impl Manager {
Expand All @@ -18,6 +21,6 @@ impl Manager {
}

let opt = opt.into() as Opt;
tasks.file_link(&self.yanked, self.cwd(), opt.relative, opt.force);
tasks.file_link(&self.yanked, self.cwd(), opt.relative, opt.hard, opt.force);
}
}
4 changes: 2 additions & 2 deletions yazi-core/src/tasks/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ impl Tasks {
}
}

pub fn file_link(&self, src: &HashSet<Url>, dest: &Url, relative: bool, force: bool) {
pub fn file_link(&self, src: &HashSet<Url>, dest: &Url, relative: bool, hard: bool, force: bool) {
for u in src {
let to = dest.join(u.file_name().unwrap());
if force && *u == to {
debug!("file_link: same file, skipping {:?}", to);
} else {
self.scheduler.file_link(u.clone(), to, relative, force);
self.scheduler.file_link(u.clone(), to, relative, hard, force);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions yazi-scheduler/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ futures = "0.3.30"
parking_lot = "0.12.3"
scopeguard = "1.2.0"
tokio = { version = "1.38.0", features = [ "full" ] }
walkdir = "2.5.0"

# Logging
tracing = { version = "0.1.40", features = [ "max_level_debug", "release_max_level_warn" ] }
Expand Down
37 changes: 27 additions & 10 deletions yazi-scheduler/src/file/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use anyhow::{anyhow, Result};
use futures::{future::BoxFuture, FutureExt};
use tokio::{fs, io::{self, ErrorKind::{AlreadyExists, NotFound}}, sync::mpsc};
use tracing::warn;
use walkdir::WalkDir;
use yazi_config::TASKS;
use yazi_shared::fs::{calculate_size, copy_with_progress, maybe_exists, ok_or_not_found, path_relative_to, Url};

Expand Down Expand Up @@ -81,16 +82,32 @@ impl File {
};

ok_or_not_found(fs::remove_file(&task.to).await)?;
#[cfg(unix)]
{
fs::symlink(src, &task.to).await?
}
#[cfg(windows)]
{
if meta.is_dir() {
fs::symlink_dir(src, &task.to).await?
} else {
fs::symlink_file(src, &task.to).await?

if task.hard {
for entry in WalkDir::new(&src) {
let entry = entry?;
let path = entry.path();
let relative_path = path.strip_prefix(&src).unwrap();
let target_path = task.to.join(relative_path);

if path.is_dir() {
fs::create_dir(&target_path).await?;
} else {
fs::hard_link(path, &target_path).await?;
}
}
} else {
#[cfg(unix)]
{
fs::symlink(src, &task.to).await?
}
#[cfg(windows)]
{
if meta.is_dir() {
fs::symlink_dir(src, &task.to).await?
} else {
fs::symlink_file(src, &task.to).await?
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions yazi-scheduler/src/file/op.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub struct FileOpLink {
pub meta: Option<Metadata>,
pub resolve: bool,
pub relative: bool,
pub hard: bool,
pub delete: bool,
}

Expand All @@ -66,6 +67,7 @@ impl From<FileOpPaste> for FileOpLink {
meta: value.meta,
resolve: true,
relative: false,
hard: false,
delete: value.cut,
}
}
Expand Down
13 changes: 11 additions & 2 deletions yazi-scheduler/src/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ impl Scheduler {
);
}

pub fn file_link(&self, from: Url, mut to: Url, relative: bool, force: bool) {
pub fn file_link(&self, from: Url, mut to: Url, relative: bool, hard: bool, force: bool) {
let name = format!("Link {from:?} to {to:?}");
let id = self.ongoing.lock().add(TaskKind::User, name);

Expand All @@ -145,7 +145,16 @@ impl Scheduler {
to = unique_path(to).await;
}
file
.link(FileOpLink { id, from, to, meta: None, resolve: false, relative, delete: false })
.link(FileOpLink {
id,
from,
to,
meta: None,
resolve: false,
relative,
hard,
delete: false,
})
.await
.ok();
}
Expand Down

0 comments on commit a90cb1c

Please sign in to comment.