This commit is contained in:
sxyazi 2024-03-12 23:06:25 +08:00
parent 0233a0e952
commit 8fe080d802
No known key found for this signature in database
10 changed files with 85 additions and 71 deletions

View file

@ -1,9 +1,9 @@
use std::{collections::HashMap, ffi::OsStr, io::{stdout, BufWriter, Write}, path::PathBuf};
use std::{borrow::Cow, collections::HashMap, ffi::{OsStr, OsString}, io::{stdout, BufWriter, Write}, path::PathBuf};
use anyhow::{anyhow, Result};
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
use yazi_config::{OPEN, PREVIEW};
use yazi_proxy::{AppProxy, HIDER, WATCHER};
use yazi_proxy::{AppProxy, TasksProxy, HIDER, WATCHER};
use yazi_shared::{fs::{accessible, max_common_root, File, FilesOp, Url}, term::Term, Defer};
use crate::manager::Manager;
@ -31,19 +31,13 @@ impl Manager {
.write_all(s.as_encoded_bytes())
.await?;
let _permit = HIDER.acquire().await.unwrap();
let _defer1 = Defer::new(AppProxy::resume);
let _defer2 = Defer::new(|| tokio::spawn(fs::remove_file(tmp.clone())));
AppProxy::stop().await;
let _defer1 = Defer::new(|| tokio::spawn(fs::remove_file(tmp.clone())));
TasksProxy::process_exec(vec![OsString::new(), tmp.to_owned().into()], Cow::Borrowed(opener))
.await;
// FIXME
// let mut child = super::shell(ShellOpt {
// cmd: (*opener.run).into(),
// args: vec![OsString::new(), tmp.to_owned().into()],
// piped: false,
// orphan: false,
// })?;
// child.wait().await?;
let _permit = HIDER.acquire().await.unwrap();
let _defer2 = Defer::new(AppProxy::resume);
AppProxy::stop().await;
let new: Vec<_> = fs::read_to_string(&tmp).await?.lines().map(PathBuf::from).collect();
Self::bulk_rename_do(cwd, root, old, new).await

View file

@ -1,4 +1,4 @@
use std::ffi::OsString;
use std::{borrow::Cow, ffi::OsString};
use tracing::error;
use yazi_boot::ARGS;
@ -87,7 +87,7 @@ impl Manager {
return tasks.process_from_files(opt.hovered, targets);
}
let openers: Vec<_> = OPEN.common_openers(&targets).into_iter().cloned().collect();
let openers: Vec<_> = OPEN.common_openers(&targets);
if openers.is_empty() {
return;
}
@ -98,7 +98,7 @@ impl Manager {
openers.iter().map(|o| o.desc.clone()).collect(),
));
if let Ok(choice) = result.await {
TasksProxy::open_with(urls, openers[choice].clone());
TasksProxy::open_with(urls, Cow::Borrowed(openers[choice]));
}
});
}

View file

@ -1,3 +1,5 @@
use std::borrow::Cow;
use yazi_config::{open::Opener, popup::InputCfg};
use yazi_proxy::{InputProxy, TasksProxy};
use yazi_shared::event::Cmd;
@ -38,14 +40,17 @@ impl Tab {
}
}
TasksProxy::open_with(selected, Opener {
TasksProxy::open_with(
selected,
Cow::Owned(Opener {
run: opt.run,
block: opt.block,
orphan: false,
desc: Default::default(),
for_: None,
spread: true,
});
}),
);
});
}
}

View file

@ -1,4 +1,4 @@
use std::{collections::HashMap, ffi::OsString, mem};
use std::{borrow::Cow, collections::HashMap, ffi::OsString, mem};
use yazi_config::{open::Opener, OPEN};
use yazi_shared::fs::Url;
@ -15,13 +15,13 @@ impl Tasks {
}
for (opener, args) in openers {
self.process_from_opener(
opener.clone(),
Cow::Borrowed(opener),
args.into_iter().map(|u| u.into_os_string()).collect(),
);
}
}
pub fn process_from_opener(&self, opener: Opener, mut args: Vec<OsString>) {
pub fn process_from_opener(&self, opener: Cow<'static, Opener>, mut args: Vec<OsString>) {
if opener.spread {
self.scheduler.process_open(opener, args, None);
return;

View file

@ -1,3 +1,5 @@
use std::borrow::Cow;
use yazi_config::open::Opener;
use yazi_shared::{event::Cmd, fs::Url};
@ -16,7 +18,7 @@ impl From<Cmd> for OpenDoOpt {
// --- Open with
pub struct OpenWithOpt {
pub targets: Vec<Url>,
pub opener: Opener,
pub opener: Cow<'static, Opener>,
}
impl TryFrom<Cmd> for OpenWithOpt {

View file

@ -1,4 +1,4 @@
use std::ffi::OsString;
use std::{borrow::Cow, ffi::OsString};
use tokio::sync::oneshot;
use yazi_config::open::Opener;
@ -6,8 +6,8 @@ use yazi_shared::event::Cmd;
// --- Exec
pub struct ProcessExecOpt {
pub opener: Opener,
pub args: Vec<OsString>,
pub opener: Cow<'static, Opener>,
pub done: oneshot::Sender<()>,
}

View file

@ -1,13 +1,26 @@
use std::{borrow::Cow, ffi::OsString};
use tokio::sync::oneshot;
use yazi_config::open::Opener;
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
use crate::options::OpenWithOpt;
use crate::options::{OpenWithOpt, ProcessExecOpt};
pub struct TasksProxy;
impl TasksProxy {
#[inline]
pub fn open_with(targets: Vec<Url>, opener: Opener) {
pub fn open_with(targets: Vec<Url>, opener: Cow<'static, Opener>) {
emit!(Call(Cmd::new("open_with").with_data(OpenWithOpt { targets, opener }), Layer::Tasks));
}
#[inline]
pub async fn process_exec(args: Vec<OsString>, opener: Cow<'static, Opener>) {
let (tx, rx) = oneshot::channel();
emit!(Call(
Cmd::new("process_exec").with_data(ProcessExecOpt { args, opener, done: tx }),
Layer::Tasks
));
rx.await.ok();
}
}

View file

@ -4,19 +4,6 @@ use tokio_util::sync::CancellationToken;
use super::ShellOpt;
#[derive(Debug)]
pub struct ProcessOpOrphan {
pub id: usize,
pub cmd: OsString,
pub args: Vec<OsString>,
}
impl From<ProcessOpOrphan> for ShellOpt {
fn from(op: ProcessOpOrphan) -> Self {
Self { cmd: op.cmd, args: op.args, piped: false, orphan: true }
}
}
#[derive(Debug)]
pub struct ProcessOpBlock {
pub id: usize,
@ -30,6 +17,19 @@ impl From<ProcessOpBlock> for ShellOpt {
}
}
#[derive(Debug)]
pub struct ProcessOpOrphan {
pub id: usize,
pub cmd: OsString,
pub args: Vec<OsString>,
}
impl From<ProcessOpOrphan> for ShellOpt {
fn from(op: ProcessOpOrphan) -> Self {
Self { cmd: op.cmd, args: op.args, piped: false, orphan: true }
}
}
#[derive(Debug)]
pub struct ProcessOpBg {
pub id: usize,

View file

@ -13,19 +13,6 @@ pub struct Process {
impl Process {
pub fn new(prog: mpsc::UnboundedSender<TaskProg>) -> Self { Self { prog } }
pub async fn orphan(&self, task: ProcessOpOrphan) -> Result<()> {
let id = task.id;
match super::shell(task.into()) {
Ok(_) => self.succ(id)?,
Err(e) => {
self.prog.send(TaskProg::New(id, 0))?;
self.fail(id, format!("Failed to spawn process: {e}"))?;
}
}
Ok(())
}
pub async fn block(&self, task: ProcessOpBlock) -> Result<()> {
let _permit = HIDER.acquire().await.unwrap();
let _defer = Defer::new(AppProxy::resume);
@ -50,6 +37,19 @@ impl Process {
self.succ(id)
}
pub async fn orphan(&self, task: ProcessOpOrphan) -> Result<()> {
let id = task.id;
match super::shell(task.into()) {
Ok(_) => self.succ(id)?,
Err(e) => {
self.prog.send(TaskProg::New(id, 0))?;
self.fail(id, format!("Failed to spawn process: {e}"))?;
}
}
Ok(())
}
pub async fn bg(&self, task: ProcessOpBg) -> Result<()> {
self.prog.send(TaskProg::New(task.id, 0))?;
let mut child =

View file

@ -1,4 +1,4 @@
use std::{ffi::OsString, sync::Arc, time::Duration};
use std::{borrow::Cow, ffi::OsString, sync::Arc, time::Duration};
use futures::{future::BoxFuture, FutureExt};
use parking_lot::Mutex;
@ -335,7 +335,7 @@ impl Scheduler {
pub fn process_open(
&self,
opener: Opener,
opener: Cow<'static, Opener>,
args: Vec<OsString>,
done: Option<oneshot::Sender<()>>,
) {
@ -369,19 +369,19 @@ impl Scheduler {
})
});
// FIXME: use micro instead
tokio::spawn({
let process = self.process.clone();
let opener = opener.clone();
_ = self.micro.try_send(
async move {
if opener.orphan {
process.orphan(ProcessOpOrphan { id, cmd: opener.run.into(), args }).await.ok();
} else if opener.block {
process.block(ProcessOpBlock { id, cmd: opener.run.into(), args }).await.ok();
if opener.block {
process.block(ProcessOpBlock { id, cmd: OsString::from(&opener.run), args }).await.ok();
} else if opener.orphan {
process.orphan(ProcessOpOrphan { id, cmd: OsString::from(&opener.run), args }).await.ok();
} else {
process.bg(ProcessOpBg { id, cmd: opener.run.into(), args, ct }).await.ok();
process.bg(ProcessOpBg { id, cmd: OsString::from(&opener.run), args, ct }).await.ok();
}
}
});
.boxed(),
HIGH,
);
}
}