summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-03-18 02:04:07 +0100
committerrabite <rabite@posteo.de>2019-03-18 02:04:07 +0100
commitc719ec7a3cb6ca3d2346f48dc11d2e0d5ee10d36 (patch)
treea01c9421041a59006a0d0236adcad95085b58f7d
parent6bb16d2638a48ebaad3ebe475df6587c29cb774c (diff)
running subshells in the foreground
-rw-r--r--src/file_browser.rs29
-rw-r--r--src/main.rs3
-rw-r--r--src/proclist.rs4
-rw-r--r--src/term.rs43
4 files changed, 65 insertions, 14 deletions
diff --git a/src/file_browser.rs b/src/file_browser.rs
index abf144f..831f96b 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -652,6 +652,34 @@ impl FileBrowser {
Ok(())
}
+ pub fn run_subshell(&mut self) -> HResult<()> {
+ self.core.get_sender().send(Events::InputEnabled(false))?;
+
+ self.core.screen.cursor_show().log();
+ self.core.screen.drop_screen();
+
+ let shell = std::env::var("SHELL").unwrap_or("bash".into());
+ let status = std::process::Command::new(&shell).status();
+
+ self.core.screen.reset_screen();
+
+
+ self.core.get_sender().send(Events::InputEnabled(true))?;
+
+ match status {
+ Ok(status) =>
+ self.show_status(&format!("\"{}\" exited with {}",
+ shell, status)).log(),
+ Err(err) =>
+ self.show_status(&format!("Can't run this \"{}\": {}",
+ shell, err)).log()
+ }
+
+
+
+ Ok(())
+ }
+
pub fn get_footer(&self) -> HResult<String> {
let xsize = self.get_coordinates()?.xsize();
let ypos = self.get_coordinates()?.position().y();
@@ -759,6 +787,7 @@ impl Widget for FileBrowser {
Key::Char('m') => { self.add_bookmark()?; },
Key::Char('w') => { self.proc_view.lock()?.popup()?; },
Key::Char('l') => self.log_view.lock()?.popup()?,
+ Key::Char('z') => self.run_subshell()?,
_ => { self.main_widget_mut()?.on_key(key)?; },
}
self.update_preview()?;
diff --git a/src/main.rs b/src/main.rs
index 0659a09..ddf7d4e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -64,11 +64,12 @@ fn main() -> HResult<()> {
// do this early so it might be ready when needed
crate::files::load_tags().ok();
- let core = WidgetCore::new().expect("Can't create WidgetCore!");
+ let mut core = WidgetCore::new().expect("Can't create WidgetCore!");
match run(core.clone()) {
Ok(_) => Ok(()),
Err(err) => {
+ core.screen.drop_screen();
eprintln!("{:?}\n{:?}", err, err.cause());
return Err(err);
}
diff --git a/src/proclist.rs b/src/proclist.rs
index 38b66fc..f05612f 100644
--- a/src/proclist.rs
+++ b/src/proclist.rs
@@ -114,7 +114,9 @@ impl Listable for ListView<Vec<Process>> {
impl ListView<Vec<Process>> {
fn run_proc(&mut self, cmd: &str) -> HResult<()> {
- let handle = std::process::Command::new("sh")
+ let shell = std::env::var("SHELL").unwrap_or("sh".into());
+
+ let handle = std::process::Command::new(shell)
.arg("-c")
.arg(cmd)
.stdin(std::process::Stdio::null())
diff --git a/src/term.rs b/src/term.rs
index 6b19c1b..94e0c5d 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -10,31 +10,47 @@ use parse_ansi::parse_bytes;
use crate::fail::HResult;
+pub type TermMode = AlternateScreen<MouseTerminal<RawTerminal<BufWriter<Stdout>>>>;
+
#[derive(Clone)]
pub struct Screen {
- screen: Arc<Mutex<RawTerminal<MouseTerminal<AlternateScreen<BufWriter<Stdout>>>>>>
+ screen: Arc<Mutex<Option<TermMode>>>
}
impl Screen {
pub fn new() -> HResult<Screen> {
- let screen = BufWriter::new(std::io::stdout());
- let screen = AlternateScreen::from(screen);
- let mut screen = MouseTerminal::from(screen).into_raw_mode()?;
+ let screen = BufWriter::new(std::io::stdout()).into_raw_mode()?;
+ let mut screen = MouseTerminal::from(screen);
+ let mut screen = AlternateScreen::from(screen);
+
screen.cursor_hide()?;
- screen.flush()?;
- screen.clear()?;
Ok(Screen {
- screen: Arc::new(Mutex::new(screen))
+ screen: Arc::new(Mutex::new(Some(screen)))
})
}
+
+ pub fn drop_screen(&mut self) {
+ self.cursor_show();
+ self.to_main_screen();
+ self.screen = Arc::new(Mutex::new(None));
+
+ // Terminal stays fucked without this. Why?
+ std::process::Command::new("reset").arg("-I").spawn();
+ }
+
+ pub fn reset_screen(&mut self) -> HResult<()> {
+ let screen = Screen::new()?.screen.lock()?.take()?;
+ *self.screen.lock()? = Some(screen);
+ Ok(())
+ }
}
impl Write for Screen {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
- self.screen.lock().unwrap().write(buf)
+ self.screen.lock().unwrap().as_mut().unwrap().write(buf)
}
fn flush(&mut self) -> std::io::Result<()> {
- self.screen.lock().unwrap().flush()
+ self.screen.lock().unwrap().as_mut().unwrap().flush()
}
}
@@ -80,12 +96,15 @@ pub trait ScreenExt: Write {
write!(self, "\x1bkhunter: {}\x1b\\", title)?;
Ok(())
}
+ fn to_main_screen(&mut self) -> HResult<()> {
+ write!(self, "{}", termion::screen::ToMainScreen)?;
+ self.flush()?;
+ Ok(())
+ }
}
-impl ScreenExt for AlternateScreen<Box<Stdout>> {}
-impl ScreenExt for AlternateScreen<Stdout> {}
-impl ScreenExt for AlternateScreen<BufWriter<Stdout>> {}
impl ScreenExt for Screen {}
+impl ScreenExt for TermMode {}
pub fn xsize() -> u16 {
let (xsize, _) = termion::terminal_size().unwrap();