mirror of https://github.com/bobwen-dev/hunter
running subshells in the foreground
This commit is contained in:
parent
6bb16d2638
commit
c719ec7a3c
|
@ -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()?;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
|
|
43
src/term.rs
43
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();
|
||||
|
|
Loading…
Reference in New Issue