Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: new orphan option for opener rules, to keep the process running even when Yazi exited #216

Merged
merged 2 commits into from
Sep 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion config/src/open/opener.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use serde::{Deserialize, Deserializer};
pub struct Opener {
pub exec: String,
pub block: bool,
pub orphan: bool,
pub display_name: String,
pub spread: bool,
}
Expand All @@ -18,6 +19,8 @@ impl<'de> Deserialize<'de> for Opener {
pub exec: String,
#[serde(default)]
pub block: bool,
#[serde(default)]
pub orphan: bool,
pub display_name: Option<String>,
}

Expand All @@ -32,6 +35,6 @@ impl<'de> Deserialize<'de> for Opener {
.unwrap_or_else(|| shadow.exec.split_whitespace().next().unwrap().to_string());

let spread = shadow.exec.contains("$*") || shadow.exec.contains("$@");
Ok(Self { exec: shadow.exec, block: shadow.block, display_name, spread })
Ok(Self { exec: shadow.exec, block: shadow.block, orphan: shadow.orphan, display_name, spread })
}
}
16 changes: 12 additions & 4 deletions core/src/external/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,17 @@ use anyhow::Result;
use tokio::process::{Child, Command};

pub struct ShellOpt {
pub cmd: OsString,
pub args: Vec<OsString>,
pub piped: bool,
pub cmd: OsString,
pub args: Vec<OsString>,
pub piped: bool,
pub orphan: bool,
}

impl ShellOpt {
pub fn with_piped(mut self) -> Self {
self.piped = true;
self
}
}

pub fn shell(opt: ShellOpt) -> Result<Child> {
Expand All @@ -21,7 +29,7 @@ pub fn shell(opt: ShellOpt) -> Result<Child> {
.stdin(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
.stdout(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
.stderr(if opt.piped { Stdio::piped() } else { Stdio::inherit() })
.kill_on_drop(true)
.kill_on_drop(!opt.orphan)
.spawn()?,
)
}
Expand Down
7 changes: 4 additions & 3 deletions core/src/manager/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,10 @@ impl Manager {
emit!(Stop(true)).await;

let mut child = external::shell(ShellOpt {
cmd: (*opener.exec).into(),
args: vec![tmp.to_owned().into()],
piped: false,
cmd: (*opener.exec).into(),
args: vec![tmp.to_owned().into()],
piped: false,
orphan: false,
})?;
child.wait().await?;

Expand Down
2 changes: 1 addition & 1 deletion core/src/manager/tab.rs
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ impl Tab {

emit!(Open(
selected,
Some(Opener { exec, block, display_name: Default::default(), spread: true })
Some(Opener { exec, block, orphan: false, display_name: Default::default(), spread: true })
));
});

Expand Down
1 change: 1 addition & 0 deletions core/src/tasks/scheduler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ impl Scheduler {
cmd: opener.exec.into(),
args,
block: opener.block,
orphan: opener.orphan,
cancel: cancel_tx,
})
.await
Expand Down
23 changes: 19 additions & 4 deletions core/src/tasks/workers/process.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ffi::OsString;
use std::{ffi::OsString, mem};

use anyhow::Result;
use tokio::{io::{AsyncBufReadExt, BufReader}, select, sync::{mpsc, oneshot}};
Expand All @@ -16,9 +16,21 @@ pub(crate) struct ProcessOpOpen {
pub cmd: OsString,
pub args: Vec<OsString>,
pub block: bool,
pub orphan: bool,
pub cancel: oneshot::Sender<()>,
}

impl From<&mut ProcessOpOpen> for ShellOpt {
fn from(value: &mut ProcessOpOpen) -> Self {
Self {
cmd: mem::take(&mut value.cmd),
args: mem::take(&mut value.args),
piped: false,
orphan: value.orphan,
}
}
}

impl Process {
pub(crate) fn new(sch: mpsc::UnboundedSender<TaskOp>) -> Self { Self { sch } }

Expand All @@ -33,7 +45,7 @@ impl Process {
let _guard = BLOCKER.acquire().await.unwrap();
emit!(Stop(true)).await;

match external::shell(ShellOpt { cmd: task.cmd, args: task.args, piped: false }) {
match external::shell(ShellOpt::from(&mut task)) {
Ok(mut child) => {
child.wait().await.ok();
}
Expand All @@ -48,13 +60,16 @@ impl Process {
}

self.sch.send(TaskOp::New(task.id, 0))?;
let mut child = external::shell(ShellOpt { cmd: task.cmd, args: task.args, piped: true })?;
let mut child = external::shell(ShellOpt::from(&mut task).with_piped())?;

let mut stdout = BufReader::new(child.stdout.take().unwrap()).lines();
let mut stderr = BufReader::new(child.stderr.take().unwrap()).lines();
loop {
select! {
_ = task.cancel.closed() => break,
_ = task.cancel.closed() => {
child.start_kill().ok();
break;
}
Ok(Some(line)) = stdout.next_line() => {
self.log(task.id, line)?;
}
Expand Down