Skip to content

Commit

Permalink
feat: new --cwd parameter for the shell command and fs.cwd() API
Browse files Browse the repository at this point in the history
  • Loading branch information
sxyazi committed Dec 17, 2024
1 parent 63ad289 commit 18d9dbe
Show file tree
Hide file tree
Showing 23 changed files with 128 additions and 88 deletions.
36 changes: 18 additions & 18 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion yazi-boot/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ serde = { workspace = true }

[build-dependencies]
clap = { workspace = true }
clap_complete = "4.5.38"
clap_complete = "4.5.39"
clap_complete_fig = "4.5.2"
clap_complete_nushell = "4.5.4"
vergen-gitcl = { version = "1.0.2", features = [ "build", "rustc" ] }
2 changes: 1 addition & 1 deletion yazi-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ yazi-shared = { path = "../yazi-shared", version = "0.4.2" }
# External build dependencies
anyhow = { workspace = true }
clap = { workspace = true }
clap_complete = "4.5.38"
clap_complete = "4.5.39"
clap_complete_fig = "4.5.2"
clap_complete_nushell = "4.5.4"
serde_json = { workspace = true }
Expand Down
8 changes: 6 additions & 2 deletions yazi-core/src/manager/commands/bulk_rename.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl Manager {
let root = max_common_root(&old);
let old: Vec<_> = old.into_iter().map(|p| p.strip_prefix(&root).unwrap().to_owned()).collect();

let cwd = self.cwd().clone();
tokio::spawn(async move {
let tmp = PREVIEW.tmpfile("bulk");
let s = old.iter().map(|o| o.as_os_str()).collect::<Vec<_>>().join(OsStr::new("\n"));
Expand All @@ -34,8 +35,11 @@ impl Manager {
.await?;

defer! { tokio::spawn(fs::remove_file(tmp.clone())); }
TasksProxy::process_exec(vec![OsString::new(), tmp.to_owned().into()], Cow::Borrowed(opener))
.await;
TasksProxy::process_exec(Cow::Borrowed(opener), cwd, vec![
OsString::new(),
tmp.to_owned().into(),
])
.await;

let _permit = HIDER.acquire().await.unwrap();
defer!(AppProxy::resume());
Expand Down
14 changes: 10 additions & 4 deletions yazi-core/src/manager/commands/open.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ impl Manager {
return;
}

let cwd = self.cwd().clone();
let (mut done, mut todo) = (Vec::with_capacity(selected.len()), vec![]);
for u in selected {
if self.mimetype.contains(u) {
Expand All @@ -53,7 +54,7 @@ impl Manager {

if todo.is_empty() {
return self
.open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive }, tasks);
.open_do(OpenDoOpt { cwd, hovered, targets: done, interactive: opt.interactive }, tasks);
}

tokio::spawn(async move {
Expand All @@ -71,7 +72,12 @@ impl Manager {
}
}

ManagerProxy::open_do(OpenDoOpt { hovered, targets: done, interactive: opt.interactive });
ManagerProxy::open_do(OpenDoOpt {
cwd,
hovered,
targets: done,
interactive: opt.interactive,
});
});
}

Expand All @@ -88,7 +94,7 @@ impl Manager {
if targets.is_empty() {
return;
} else if !opt.interactive {
return tasks.process_from_files(opt.hovered, targets);
return tasks.process_from_files(opt.cwd, opt.hovered, targets);
}

let openers: Vec<_> = OPEN.common_openers(&targets);
Expand All @@ -102,7 +108,7 @@ impl Manager {
openers.iter().map(|o| o.desc.clone()).collect(),
));
if let Ok(choice) = result.await {
TasksProxy::open_with(urls, Cow::Borrowed(openers[choice]));
TasksProxy::open_with(Cow::Borrowed(openers[choice]), opt.cwd, urls);
}
});
}
Expand Down
20 changes: 14 additions & 6 deletions yazi-core/src/tab/commands/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,34 @@ use std::{borrow::Cow, fmt::Display};
use anyhow::bail;
use yazi_config::{open::Opener, popup::InputCfg};
use yazi_proxy::{AppProxy, InputProxy, TasksProxy};
use yazi_shared::event::{CmdCow, Data};
use yazi_shared::{event::{CmdCow, Data}, url::Url};

use crate::tab::Tab;

pub struct Opt {
run: Cow<'static, str>,
run: Cow<'static, str>,
cwd: Option<Url>,

block: bool,
orphan: bool,
interactive: bool,
cursor: Option<usize>,

cursor: Option<usize>,
}

impl TryFrom<CmdCow> for Opt {
type Error = anyhow::Error;

fn try_from(mut c: CmdCow) -> Result<Self, Self::Error> {
let me = Self {
run: c.take_first_str().unwrap_or_default(),
run: c.take_first_str().unwrap_or_default(),
cwd: c.take_url("cwd"),

block: c.bool("block"),
orphan: c.bool("orphan"),
interactive: c.bool("interactive"),
cursor: c.get("cursor").and_then(Data::as_usize),

cursor: c.get("cursor").and_then(Data::as_usize),
};

if me.cursor.is_some_and(|c| c > me.run.chars().count()) {
Expand All @@ -46,6 +52,7 @@ impl Tab {
Err(e) => return AppProxy::notify_warn("`shell` command", e),
};

let cwd = opt.cwd.take().unwrap_or_else(|| self.cwd().clone());
let selected = self.hovered_and_selected(true).cloned().collect();
tokio::spawn(async move {
if opt.interactive {
Expand All @@ -61,7 +68,6 @@ impl Tab {
}

TasksProxy::open_with(
selected,
Cow::Owned(Opener {
run: opt.run.into_owned(),
block: opt.block,
Expand All @@ -70,6 +76,8 @@ impl Tab {
for_: None,
spread: true,
}),
cwd,
selected,
);
});
}
Expand Down
1 change: 1 addition & 0 deletions yazi-core/src/tasks/commands/open_with.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ impl Tasks {
pub fn open_with(&mut self, opt: impl TryInto<OpenWithOpt>) {
if let Ok(opt) = opt.try_into() {
self.process_from_opener(
opt.cwd,
opt.opener,
opt.targets.into_iter().map(|u| u.into_path().into_os_string()).collect(),
);
Expand Down
2 changes: 1 addition & 1 deletion yazi-core/src/tasks/commands/process_exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::tasks::Tasks;
impl Tasks {
pub fn process_exec(&mut self, opt: impl TryInto<ProcessExecOpt>) {
if let Ok(opt) = opt.try_into() {
self.scheduler.process_open(opt.opener, opt.args, Some(opt.done));
self.scheduler.process_open(opt);
}
}
}
22 changes: 17 additions & 5 deletions yazi-core/src/tasks/process.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use std::{borrow::Cow, collections::HashMap, ffi::OsString, mem};

use yazi_config::{OPEN, open::Opener};
use yazi_proxy::options::ProcessExecOpt;
use yazi_shared::url::Url;

use super::Tasks;

impl Tasks {
pub fn process_from_files(&self, hovered: Url, targets: Vec<(Url, Cow<str>)>) {
pub fn process_from_files(&self, cwd: Url, hovered: Url, targets: Vec<(Url, Cow<str>)>) {
let mut openers = HashMap::new();
for (url, mime) in targets {
if let Some(opener) = OPEN.openers(&url, mime).and_then(|o| o.first().copied()) {
Expand All @@ -15,27 +16,38 @@ impl Tasks {
}
for (opener, args) in openers {
self.process_from_opener(
cwd.clone(),
Cow::Borrowed(opener),
args.into_iter().map(|u| u.into_path().into_os_string()).collect(),
);
}
}

pub fn process_from_opener(&self, opener: Cow<'static, Opener>, mut args: Vec<OsString>) {
pub fn process_from_opener(
&self,
cwd: Url,
opener: Cow<'static, Opener>,
mut args: Vec<OsString>,
) {
if opener.spread {
self.scheduler.process_open(opener, args, None);
self.scheduler.process_open(ProcessExecOpt { cwd, opener, args, done: None });
return;
}
if args.is_empty() {
return;
}
if args.len() == 2 {
self.scheduler.process_open(opener, args, None);
self.scheduler.process_open(ProcessExecOpt { cwd, opener, args, done: None });
return;
}
let hovered = mem::take(&mut args[0]);
for target in args.into_iter().skip(1) {
self.scheduler.process_open(opener.clone(), vec![hovered.clone(), target], None);
self.scheduler.process_open(ProcessExecOpt {
cwd: cwd.clone(),
opener: opener.clone(),
args: vec![hovered.clone(), target],
done: None,
});
}
}
}
1 change: 1 addition & 0 deletions yazi-plugin/preset/plugins/zoxide.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ local function setup(_, opts)
"cd",
function()
ya.manager_emit("shell", {
cwd = fs.cwd(),
orphan = true,
"zoxide add " .. ya.quote(tostring(cx.active.current.cwd)),
})
Expand Down
11 changes: 1 addition & 10 deletions yazi-plugin/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ impl Clipboard {
use std::os::unix::prelude::OsStringExt;

use tokio::process::Command;
use yazi_fs::CWD;
use yazi_shared::in_ssh_connection;

if in_ssh_connection() {
Expand All @@ -31,13 +30,7 @@ impl Clipboard {
];

for (bin, args) in all {
let Ok(output) = Command::new(bin)
.args(args)
.current_dir(CWD.load().as_ref())
.kill_on_drop(true)
.output()
.await
else {
let Ok(output) = Command::new(bin).args(args).kill_on_drop(true).output().await else {
continue;
};
if output.status.success() {
Expand Down Expand Up @@ -65,7 +58,6 @@ impl Clipboard {

use crossterm::execute;
use tokio::{io::AsyncWriteExt, process::Command};
use yazi_fs::CWD;

s.as_ref().clone_into(&mut self.content.lock());
execute!(BufWriter::new(stderr()), osc52::SetClipboard::new(s.as_ref())).ok();
Expand All @@ -80,7 +72,6 @@ impl Clipboard {
for (bin, args) in all {
let cmd = Command::new(bin)
.args(args)
.current_dir(CWD.load().as_ref())
.stdin(Stdio::piped())
.stdout(Stdio::null())
.stderr(Stdio::null())
Expand Down
3 changes: 1 addition & 2 deletions yazi-plugin/src/external/fd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::process::Stdio;

use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, process::{Child, Command}, sync::mpsc::{self, UnboundedReceiver}};
use yazi_fs::{CWD, File};
use yazi_fs::File;
use yazi_shared::url::Url;

pub struct FdOpt {
Expand Down Expand Up @@ -37,7 +37,6 @@ fn spawn(program: &str, opt: &FdOpt) -> std::io::Result<Child> {
.arg(if opt.hidden { "--hidden" } else { "--no-hidden" })
.args(&opt.args)
.arg(&opt.subject)
.current_dir(CWD.load().as_ref())
.kill_on_drop(true)
.stdout(Stdio::piped())
.stderr(Stdio::null())
Expand Down
Loading

0 comments on commit 18d9dbe

Please sign in to comment.