summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-06-16 14:57:00 +0200
committerrabite <rabite@posteo.de>2019-06-16 14:57:00 +0200
commit1b596e73c16a3d20122a5648933d8c62e8a13077 (patch)
treea5b9980945f0298ca3967baba999ca2d515ce4ad
parent48cbbf3b8850992d23bf822be46144fbf0e443b5 (diff)
added subprocesses running in foreground by appending !
-rw-r--r--src/file_browser.rs2
-rw-r--r--src/proclist.rs101
2 files changed, 92 insertions, 11 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 8361580..9881d73 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -1067,7 +1067,7 @@ impl FileBrowser {
let selected_file = self.selected_file().ok();
let selected_files = self.selected_files().ok();
- let cmd = self.core.minibuffer("exec")?.trim_start().to_string() + " ";
+ let cmd = self.core.minibuffer("exec")?.to_string() + " ";
let cwd_files = selected_files.map(|selected_files| {
if selected_files.len() == 0 {
diff --git a/src/proclist.rs b/src/proclist.rs
index 05541bf..7115234 100644
--- a/src/proclist.rs
+++ b/src/proclist.rs
@@ -1,10 +1,10 @@
use std::sync::{Arc, Mutex};
use std::sync::mpsc::Sender;
-use std::process::Child;
+use std::process::{Child, Command};
use std::os::unix::process::{CommandExt, ExitStatusExt};
use std::io::{BufRead, BufReader};
-use std::ffi::OsString;
-use std::os::unix::ffi::OsStringExt;
+use std::ffi::{OsString, OsStr};
+use std::os::unix::ffi::{OsStringExt, OsStrExt};
use termion::event::Key;
use unicode_width::UnicodeWidthStr;
@@ -19,7 +19,7 @@ use crate::preview::AsyncWidget;
use crate::dirty::Dirtyable;
use crate::hbox::HBox;
use crate::fail::{HResult, HError, ErrorLog};
-use crate::term;
+use crate::term::{self, ScreenExt};
use crate::files::File;
#[derive(Debug)]
@@ -208,19 +208,29 @@ impl ListView<Vec<Process>> {
fn run_proc_subshell(&mut self, mut cmd: Cmd) -> HResult<()> {
let shell = std::env::var("SHELL").unwrap_or("sh".into());
let home = crate::paths::home_path()?.into_os_string();
+ let fg = cmd.cmd.as_bytes().ends_with(b"! ");
+
+ if fg {
+ // remove that last !
+ let real_len = cmd.cmd.as_bytes().len() - 2;
+ cmd.cmd = OsString::from_vec(cmd.cmd.as_bytes()[0..real_len].to_vec());
+ // workaround until split is fixed
+ cmd.cmd.push(" ");
+ }
let cmd_args = cmd.process();
- let short = OsString::from("~");
+ let short = OsStr::from_bytes("~".as_bytes());
let short_cmd = cmd_args
.concat()
.replace(&home, &short)
- .replace(&OsString::from("\""), &OsString::from(""))
+ .replace(OsStr::from_bytes("'\''".as_bytes()),
+ OsStr::from_bytes("'".as_bytes()))
+ .replace(OsStr::from_bytes("\"".as_bytes()),
+ OsStr::from_bytes("".as_bytes()))
.to_string_lossy()
.to_string();
- self.core.show_status(&format!("Running: {}", &short_cmd)).log();
-
let shell_args = cmd_args.concat();
let shell_args = vec![OsString::from("-c"), shell_args.clone()];
@@ -228,7 +238,17 @@ impl ListView<Vec<Process>> {
cmd.args = Some(shell_args.clone());
cmd.short_cmd = Some(short_cmd);
- self.run_proc_raw(cmd)
+ if !fg {
+ self.run_proc_raw(cmd)
+ } else {
+ self.run_proc_raw_fg(cmd).log();
+
+ // Command might fail/return early. do this here
+ self.core.screen.reset()?;
+ self.core.screen.activate()?;
+ self.core.screen.clear()?;
+ Ok(())
+ }
}
fn run_proc_raw(&mut self, cmd: Cmd) -> HResult<()> {
@@ -241,7 +261,7 @@ impl ListView<Vec<Process>> {
self.core.show_status(&format!("Running: {}", &short_cmd)).log();
- let handle = std::process::Command::new(real_cmd)
+ let handle = Command::new(real_cmd)
.args(args)
.stdin(std::process::Stdio::null())
.stdout(std::process::Stdio::piped())
@@ -260,6 +280,67 @@ impl ListView<Vec<Process>> {
Ok(())
}
+ fn run_proc_raw_fg(&mut self, cmd: Cmd) -> HResult<()> {
+ let real_cmd = cmd.cmd;
+ let short_cmd = cmd.short_cmd
+ .unwrap_or(real_cmd
+ .to_string_lossy()
+ .to_string());
+ let args = cmd.args.unwrap_or(vec![]);
+
+ self.core.show_status(&format!("Running (fg): {}", &short_cmd)).log();
+
+ self.core.screen.goto_xy(0,0)?;
+ self.core.screen.reset()?;
+ self.core.screen.suspend()?;
+
+ match Command::new(real_cmd)
+ .args(args)
+ .status() {
+ Ok(status) => {
+ let color_success =
+ if status.success() {
+ format!("{}successfully", term::color_green())
+ } else {
+ format!("{}unsuccessfully", term::color_red())
+ };
+
+ let color_status =
+ if status.success() {
+ format!("{}{}",
+ term::color_green(),
+ status.code().unwrap_or(status
+ .signal()
+ .unwrap_or(-1)))
+ } else {
+ format!("{}{}",
+ term::color_red(),
+ status.code().unwrap_or(status
+ .signal()
+ .unwrap_or(-1)))
+
+ };
+
+
+ let procinfo = format!("{} exited {}{}{} with status: {}",
+ short_cmd,
+ color_success,
+ term::reset(),
+ term::status_bg(),
+ color_status);
+
+ self.core.show_status(&procinfo)?;
+ },
+ err @ Err(_) => {
+ self.core.show_status(&format!("{}{} ",
+ "Couldn't start process:",
+ short_cmd))?;
+ err?;
+ }
+ }
+ Ok(())
+ }
+
fn kill_proc(&mut self) -> HResult<()> {
let proc = self.selected_proc()?;
proc.handle.lock()?.kill()?;