mirror of
https://github.com/sxyazi/yazi.git
synced 2026-07-25 08:41:05 +00:00
..
This commit is contained in:
parent
0233a0e952
commit
8fe080d802
10 changed files with 85 additions and 71 deletions
|
|
@ -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 anyhow::{anyhow, Result};
|
||||||
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
|
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
|
||||||
use yazi_config::{OPEN, PREVIEW};
|
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 yazi_shared::{fs::{accessible, max_common_root, File, FilesOp, Url}, term::Term, Defer};
|
||||||
|
|
||||||
use crate::manager::Manager;
|
use crate::manager::Manager;
|
||||||
|
|
@ -31,19 +31,13 @@ impl Manager {
|
||||||
.write_all(s.as_encoded_bytes())
|
.write_all(s.as_encoded_bytes())
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let _permit = HIDER.acquire().await.unwrap();
|
let _defer1 = Defer::new(|| tokio::spawn(fs::remove_file(tmp.clone())));
|
||||||
let _defer1 = Defer::new(AppProxy::resume);
|
TasksProxy::process_exec(vec![OsString::new(), tmp.to_owned().into()], Cow::Borrowed(opener))
|
||||||
let _defer2 = Defer::new(|| tokio::spawn(fs::remove_file(tmp.clone())));
|
.await;
|
||||||
AppProxy::stop().await;
|
|
||||||
|
|
||||||
// FIXME
|
let _permit = HIDER.acquire().await.unwrap();
|
||||||
// let mut child = super::shell(ShellOpt {
|
let _defer2 = Defer::new(AppProxy::resume);
|
||||||
// cmd: (*opener.run).into(),
|
AppProxy::stop().await;
|
||||||
// args: vec![OsString::new(), tmp.to_owned().into()],
|
|
||||||
// piped: false,
|
|
||||||
// orphan: false,
|
|
||||||
// })?;
|
|
||||||
// child.wait().await?;
|
|
||||||
|
|
||||||
let new: Vec<_> = fs::read_to_string(&tmp).await?.lines().map(PathBuf::from).collect();
|
let new: Vec<_> = fs::read_to_string(&tmp).await?.lines().map(PathBuf::from).collect();
|
||||||
Self::bulk_rename_do(cwd, root, old, new).await
|
Self::bulk_rename_do(cwd, root, old, new).await
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ffi::OsString;
|
use std::{borrow::Cow, ffi::OsString};
|
||||||
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
use yazi_boot::ARGS;
|
use yazi_boot::ARGS;
|
||||||
|
|
@ -87,7 +87,7 @@ impl Manager {
|
||||||
return tasks.process_from_files(opt.hovered, targets);
|
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() {
|
if openers.is_empty() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -98,7 +98,7 @@ impl Manager {
|
||||||
openers.iter().map(|o| o.desc.clone()).collect(),
|
openers.iter().map(|o| o.desc.clone()).collect(),
|
||||||
));
|
));
|
||||||
if let Ok(choice) = result.await {
|
if let Ok(choice) = result.await {
|
||||||
TasksProxy::open_with(urls, openers[choice].clone());
|
TasksProxy::open_with(urls, Cow::Borrowed(openers[choice]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use yazi_config::{open::Opener, popup::InputCfg};
|
use yazi_config::{open::Opener, popup::InputCfg};
|
||||||
use yazi_proxy::{InputProxy, TasksProxy};
|
use yazi_proxy::{InputProxy, TasksProxy};
|
||||||
use yazi_shared::event::Cmd;
|
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,
|
run: opt.run,
|
||||||
block: opt.block,
|
block: opt.block,
|
||||||
orphan: false,
|
orphan: false,
|
||||||
desc: Default::default(),
|
desc: Default::default(),
|
||||||
for_: None,
|
for_: None,
|
||||||
spread: true,
|
spread: true,
|
||||||
});
|
}),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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_config::{open::Opener, OPEN};
|
||||||
use yazi_shared::fs::Url;
|
use yazi_shared::fs::Url;
|
||||||
|
|
@ -15,13 +15,13 @@ impl Tasks {
|
||||||
}
|
}
|
||||||
for (opener, args) in openers {
|
for (opener, args) in openers {
|
||||||
self.process_from_opener(
|
self.process_from_opener(
|
||||||
opener.clone(),
|
Cow::Borrowed(opener),
|
||||||
args.into_iter().map(|u| u.into_os_string()).collect(),
|
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 {
|
if opener.spread {
|
||||||
self.scheduler.process_open(opener, args, None);
|
self.scheduler.process_open(opener, args, None);
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use yazi_config::open::Opener;
|
use yazi_config::open::Opener;
|
||||||
use yazi_shared::{event::Cmd, fs::Url};
|
use yazi_shared::{event::Cmd, fs::Url};
|
||||||
|
|
||||||
|
|
@ -16,7 +18,7 @@ impl From<Cmd> for OpenDoOpt {
|
||||||
// --- Open with
|
// --- Open with
|
||||||
pub struct OpenWithOpt {
|
pub struct OpenWithOpt {
|
||||||
pub targets: Vec<Url>,
|
pub targets: Vec<Url>,
|
||||||
pub opener: Opener,
|
pub opener: Cow<'static, Opener>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<Cmd> for OpenWithOpt {
|
impl TryFrom<Cmd> for OpenWithOpt {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::ffi::OsString;
|
use std::{borrow::Cow, ffi::OsString};
|
||||||
|
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use yazi_config::open::Opener;
|
use yazi_config::open::Opener;
|
||||||
|
|
@ -6,8 +6,8 @@ use yazi_shared::event::Cmd;
|
||||||
|
|
||||||
// --- Exec
|
// --- Exec
|
||||||
pub struct ProcessExecOpt {
|
pub struct ProcessExecOpt {
|
||||||
pub opener: Opener,
|
|
||||||
pub args: Vec<OsString>,
|
pub args: Vec<OsString>,
|
||||||
|
pub opener: Cow<'static, Opener>,
|
||||||
pub done: oneshot::Sender<()>,
|
pub done: oneshot::Sender<()>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,26 @@
|
||||||
|
use std::{borrow::Cow, ffi::OsString};
|
||||||
|
|
||||||
|
use tokio::sync::oneshot;
|
||||||
use yazi_config::open::Opener;
|
use yazi_config::open::Opener;
|
||||||
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
use yazi_shared::{emit, event::Cmd, fs::Url, Layer};
|
||||||
|
|
||||||
use crate::options::OpenWithOpt;
|
use crate::options::{OpenWithOpt, ProcessExecOpt};
|
||||||
|
|
||||||
pub struct TasksProxy;
|
pub struct TasksProxy;
|
||||||
|
|
||||||
impl TasksProxy {
|
impl TasksProxy {
|
||||||
#[inline]
|
#[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));
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,19 +4,6 @@ use tokio_util::sync::CancellationToken;
|
||||||
|
|
||||||
use super::ShellOpt;
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct ProcessOpBlock {
|
pub struct ProcessOpBlock {
|
||||||
pub id: usize,
|
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)]
|
#[derive(Debug)]
|
||||||
pub struct ProcessOpBg {
|
pub struct ProcessOpBg {
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,6 @@ pub struct Process {
|
||||||
impl Process {
|
impl Process {
|
||||||
pub fn new(prog: mpsc::UnboundedSender<TaskProg>) -> Self { Self { prog } }
|
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<()> {
|
pub async fn block(&self, task: ProcessOpBlock) -> Result<()> {
|
||||||
let _permit = HIDER.acquire().await.unwrap();
|
let _permit = HIDER.acquire().await.unwrap();
|
||||||
let _defer = Defer::new(AppProxy::resume);
|
let _defer = Defer::new(AppProxy::resume);
|
||||||
|
|
@ -50,6 +37,19 @@ impl Process {
|
||||||
self.succ(id)
|
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<()> {
|
pub async fn bg(&self, task: ProcessOpBg) -> Result<()> {
|
||||||
self.prog.send(TaskProg::New(task.id, 0))?;
|
self.prog.send(TaskProg::New(task.id, 0))?;
|
||||||
let mut child =
|
let mut child =
|
||||||
|
|
|
||||||
|
|
@ -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 futures::{future::BoxFuture, FutureExt};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
|
|
@ -335,7 +335,7 @@ impl Scheduler {
|
||||||
|
|
||||||
pub fn process_open(
|
pub fn process_open(
|
||||||
&self,
|
&self,
|
||||||
opener: Opener,
|
opener: Cow<'static, Opener>,
|
||||||
args: Vec<OsString>,
|
args: Vec<OsString>,
|
||||||
done: Option<oneshot::Sender<()>>,
|
done: Option<oneshot::Sender<()>>,
|
||||||
) {
|
) {
|
||||||
|
|
@ -369,19 +369,19 @@ impl Scheduler {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
// FIXME: use micro instead
|
|
||||||
tokio::spawn({
|
|
||||||
let process = self.process.clone();
|
let process = self.process.clone();
|
||||||
let opener = opener.clone();
|
_ = self.micro.try_send(
|
||||||
async move {
|
async move {
|
||||||
if opener.orphan {
|
if opener.block {
|
||||||
process.orphan(ProcessOpOrphan { id, cmd: opener.run.into(), args }).await.ok();
|
process.block(ProcessOpBlock { id, cmd: OsString::from(&opener.run), args }).await.ok();
|
||||||
} else if opener.block {
|
} else if opener.orphan {
|
||||||
process.block(ProcessOpBlock { id, cmd: opener.run.into(), args }).await.ok();
|
process.orphan(ProcessOpOrphan { id, cmd: OsString::from(&opener.run), args }).await.ok();
|
||||||
} else {
|
} 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,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue