Skip to content

Commit

Permalink
feat: new orphan option for opener rules, to keep the process runni…
Browse files Browse the repository at this point in the history
…ng even when Yazi exited (#216)
  • Loading branch information
sxyazi authored Sep 24, 2023
1 parent e2ead7e commit d3ed8e7
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 13 deletions.
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

0 comments on commit d3ed8e7

Please sign in to comment.