Various changes
This commit is contained in:
53
src/main.rs
53
src/main.rs
@@ -1,3 +1,4 @@
|
||||
mod ansi;
|
||||
mod app;
|
||||
mod config;
|
||||
mod error;
|
||||
@@ -69,10 +70,62 @@ async fn run_app(
|
||||
if app.handle_event(event).await? {
|
||||
break;
|
||||
}
|
||||
|
||||
// After handling events, check if a script requested an exec.
|
||||
if let Some(exec) = app.pending_exec.take() {
|
||||
run_exec(terminal, exec).await?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Suspends ratatui, hands the terminal to an external interactive process,
|
||||
/// then restores the TUI and sends the exit code back to the script.
|
||||
async fn run_exec(
|
||||
terminal: &mut Terminal<CrosstermBackend<io::Stdout>>,
|
||||
exec: app::PendingExec,
|
||||
) -> Result<()> {
|
||||
// ── Suspend ratatui ──────────────────────────────────────────────────────
|
||||
disable_raw_mode()?;
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
LeaveAlternateScreen,
|
||||
DisableMouseCapture
|
||||
)?;
|
||||
terminal.show_cursor()?;
|
||||
|
||||
// ── Run the program with inherited stdin/stdout/stderr ───────────────────
|
||||
let exit_code = tokio::task::spawn_blocking({
|
||||
let shell = exec.shell.clone();
|
||||
move || {
|
||||
std::process::Command::new("bash")
|
||||
.arg("-c")
|
||||
.arg(&shell)
|
||||
.stdin(std::process::Stdio::inherit())
|
||||
.stdout(std::process::Stdio::inherit())
|
||||
.stderr(std::process::Stdio::inherit())
|
||||
.status()
|
||||
.map(|s| s.code().unwrap_or(1))
|
||||
.unwrap_or(1)
|
||||
}
|
||||
})
|
||||
.await?;
|
||||
|
||||
// ── Restore ratatui ──────────────────────────────────────────────────────
|
||||
enable_raw_mode()?;
|
||||
execute!(
|
||||
terminal.backend_mut(),
|
||||
EnterAlternateScreen,
|
||||
EnableMouseCapture
|
||||
)?;
|
||||
terminal.clear()?;
|
||||
|
||||
// ── Reply to the script with the exit code ───────────────────────────────
|
||||
let _ = exec.reply_tx.send(exit_code.to_string());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn read_crossterm_event() -> Result<Option<crossterm::event::Event>> {
|
||||
if crossterm::event::poll(std::time::Duration::from_millis(100))? {
|
||||
Ok(Some(crossterm::event::read()?))
|
||||
|
||||
Reference in New Issue
Block a user