use std::io::Write;
use brush_core::{ExecutionResult, builtins, jobs, sys};
use clap::Parser;
#[derive(Parser)]
pub(crate) struct FgCommand {
job_spec: Option<String>,
}
impl builtins::Command for FgCommand {
type Error = brush_core::Error;
async fn execute<SE: brush_core::ShellExtensions>(
&self,
context: brush_core::ExecutionContext<'_, SE>,
) -> Result<brush_core::ExecutionResult, Self::Error> {
let mut stderr = context.stdout();
let is_interactive = context.shell.options().interactive;
if let Some(job_spec) = &self.job_spec {
if let Some(job) = context.shell.jobs_mut().resolve_job_spec(job_spec) {
job.move_to_foreground()?;
writeln!(stderr, "{}", job.command_line)?;
let result = job.wait().await?;
if is_interactive {
sys::terminal::move_self_to_foreground()?;
}
if matches!(job.state, jobs::JobState::Stopped) {
let formatted = job.to_string();
writeln!(context.stderr(), "\r{formatted}")?;
}
Ok(result)
} else {
writeln!(stderr, "{}: {}: no such job", job_spec, context.command_name)?;
Ok(ExecutionResult::general_error())
}
} else {
if let Some(job) = context.shell.jobs_mut().current_job_mut() {
job.move_to_foreground()?;
writeln!(stderr, "{}", job.command_line)?;
let result = job.wait().await?;
if is_interactive {
sys::terminal::move_self_to_foreground()?;
}
if matches!(job.state, jobs::JobState::Stopped) {
let formatted = job.to_string();
writeln!(context.stderr(), "\r{formatted}")?;
}
Ok(result)
} else {
writeln!(stderr, "{}: no current job", context.command_name)?;
Ok(ExecutionResult::general_error())
}
}
}
}