fix: inconsistent stdin when running in non-blocking mode

This commit is contained in:
sxyazi 2023-08-19 19:37:38 +08:00
parent 47846932d4
commit 970d36b069
No known key found for this signature in database
4 changed files with 30 additions and 24 deletions

View file

@ -106,7 +106,8 @@ impl Executor {
}
"create" => cx.manager.create(),
"rename" => cx.manager.rename(),
"shell" => cx.manager.shell(
"copy" => cx.manager.copy(),
"shell" => cx.manager.active().shell(
exec.args.get(0).map(|e| e.as_str()).unwrap_or(""),
exec.named.contains_key("block"),
exec.named.contains_key("confirm"),

View file

@ -18,6 +18,7 @@ pub fn shell(opt: ShellOpt) -> Result<Child> {
.arg(opt.cmd)
.arg("") // $0 is the command name
.args(opt.args)
.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)
@ -32,6 +33,7 @@ pub fn shell(opt: ShellOpt) -> Result<Child> {
.arg("/C")
.arg(opt.cmd)
.args(opt.args)
.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)

View file

@ -1,7 +1,7 @@
use std::{collections::{BTreeMap, BTreeSet, HashMap, HashSet}, env, ffi::OsStr, io::{stdout, BufWriter, Write}, mem, path::{Path, PathBuf}};
use anyhow::{anyhow, bail, Error, Result};
use config::{open::Opener, BOOT, OPEN};
use config::{BOOT, OPEN};
use shared::{max_common_root, Defer, Term, MIME_DIR};
use tokio::{fs::{self, OpenOptions}, io::{stdin, AsyncReadExt, AsyncWriteExt}};
@ -85,9 +85,6 @@ impl Manager {
false
}
#[inline]
pub fn yanked(&self) -> &(bool, HashSet<PathBuf>) { &self.yanked }
pub fn quit(&self, tasks: &Tasks) -> bool {
let tasks = tasks.len();
if tasks == 0 {
@ -322,25 +319,7 @@ impl Manager {
Ok(())
}
pub fn shell(&self, exec: &str, block: bool, confirm: bool) -> bool {
let mut exec = exec.to_owned();
tokio::spawn(async move {
if !confirm || exec.is_empty() {
let result = emit!(Input(InputOpt::top("Shell:").with_value(&exec).with_highlight()));
match result.await {
Ok(e) => exec = e,
Err(_) => return,
}
}
emit!(Open(
Default::default(),
Some(Opener { exec, block, display_name: Default::default(), spread: true })
));
});
false
}
pub fn copy(&self) -> bool { false }
pub fn update_read(&mut self, op: FilesOp) -> bool {
let path = op.path();
@ -459,6 +438,9 @@ impl Manager {
#[inline]
pub fn hovered(&self) -> Option<&File> { self.tabs.active().current.hovered.as_ref() }
#[inline]
pub fn yanked(&self) -> &(bool, HashSet<PathBuf>) { &self.yanked }
pub fn selected(&self) -> Vec<&File> {
let mode = &self.active().mode;
let files = &self.current().files;

View file

@ -1,6 +1,7 @@
use std::{collections::{BTreeMap, BTreeSet}, mem, path::{Path, PathBuf}};
use anyhow::{Error, Result};
use config::open::Opener;
use shared::Defer;
use tokio::task::JoinHandle;
@ -247,6 +248,26 @@ impl Tab {
false
}
pub fn shell(&self, exec: &str, block: bool, confirm: bool) -> bool {
let mut exec = exec.to_owned();
tokio::spawn(async move {
if !confirm || exec.is_empty() {
let result = emit!(Input(InputOpt::top("Shell:").with_value(&exec).with_highlight()));
match result.await {
Ok(e) => exec = e,
Err(_) => return,
}
}
emit!(Open(
Default::default(),
Some(Opener { exec, block, display_name: Default::default(), spread: true })
));
});
false
}
pub fn select(&mut self, state: Option<bool>) -> bool {
let idx = Some(self.current.cursor());
self.current.select(idx, state)