From cf0fd5f7fe541f6d70b2f330c2bcdd9a24286fb9 Mon Sep 17 00:00:00 2001 From: Sven Kanoldt Date: Sat, 20 Dec 2025 00:12:49 +0100 Subject: [PATCH 1/2] fix: support passing arguments to shell program Allow users to pass arguments to the shell/program using trailing arguments (e.g., `t-rec -- /bin/bash -l`). This enables launching shells with specific flags like login shell mode. --- src/cli.rs | 7 ++++--- src/main.rs | 16 +++++++--------- src/utils.rs | 6 +++++- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 691d5cb7..62feacd5 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -95,9 +95,10 @@ pub struct CliArgs { #[arg(short = 'f', long, value_parser = clap::value_parser!(u8).range(4..=15))] pub fps: Option, - /// Shell or program to launch. Defaults to $SHELL - #[arg()] - pub program: Option, + /// Shell or program to launch with optional arguments. Defaults to $SHELL. + /// Use -- to separate t-rec options from shell arguments (e.g., t-rec -- /bin/bash -l) + #[arg(trailing_var_arg = true, allow_hyphen_values = true)] + pub program: Vec, // --- Config-related args (not part of recording settings) --- /// Use a named profile from the config file diff --git a/src/main.rs b/src/main.rs index aad92065..4d1fc662 100644 --- a/src/main.rs +++ b/src/main.rs @@ -89,14 +89,11 @@ fn main() -> Result<()> { let settings = resolve_profiled_settings(&args)?; - let program: String = { - if let Some(prog) = &args.program { - prog.to_string() - } else { - let default = DEFAULT_SHELL.to_owned(); - env::var("SHELL").unwrap_or(default) - } - }; + let (program, program_args): (String, Vec) = args + .program + .split_first() + .map(|(prog, rest)| (prog.clone(), rest.to_vec())) + .unwrap_or_else(|| (env::var("SHELL").unwrap_or_else(|_| DEFAULT_SHELL.to_owned()), vec![])); let (win_id, window_name) = current_win_id(&args)?; let mut api = setup()?; api.calibrate(win_id)?; @@ -137,7 +134,8 @@ fn main() -> Result<()> { }; thread::spawn(move || -> Result<()> { capture_thread(&rx, api, ctx) }) }; - let interact = thread::spawn(move || -> Result<()> { sub_shell_thread(&program).map(|_| ()) }); + let interact = + thread::spawn(move || -> Result<()> { sub_shell_thread(&program, &program_args).map(|_| ()) }); clear_screen(); io::stdout().flush().unwrap(); diff --git a/src/utils.rs b/src/utils.rs index da81369f..68de9700 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -13,8 +13,12 @@ pub fn file_name_for(tc: &u128, ext: &str) -> String { /// starts the main program and keeps interacting with the user /// blocks until termination -pub fn sub_shell_thread + Clone>(program: T) -> Result { +pub fn sub_shell_thread + Clone, A: AsRef>( + program: T, + args: &[A], +) -> Result { Command::new(program.clone()) + .args(args) .spawn() .context(format!("failed to start {:?}", program.as_ref()))? .wait() From 4d605c85d30d3505a8c264ac5e5e57f84b8f7901 Mon Sep 17 00:00:00 2001 From: Sven Kanoldt Date: Sat, 20 Dec 2025 00:45:08 +0100 Subject: [PATCH 2/2] chore: fix fmt Signed-off-by: Sven Kanoldt --- src/main.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main.rs b/src/main.rs index 4d1fc662..53cdd994 100644 --- a/src/main.rs +++ b/src/main.rs @@ -93,7 +93,12 @@ fn main() -> Result<()> { .program .split_first() .map(|(prog, rest)| (prog.clone(), rest.to_vec())) - .unwrap_or_else(|| (env::var("SHELL").unwrap_or_else(|_| DEFAULT_SHELL.to_owned()), vec![])); + .unwrap_or_else(|| { + ( + env::var("SHELL").unwrap_or_else(|_| DEFAULT_SHELL.to_owned()), + vec![], + ) + }); let (win_id, window_name) = current_win_id(&args)?; let mut api = setup()?; api.calibrate(win_id)?; @@ -134,8 +139,9 @@ fn main() -> Result<()> { }; thread::spawn(move || -> Result<()> { capture_thread(&rx, api, ctx) }) }; - let interact = - thread::spawn(move || -> Result<()> { sub_shell_thread(&program, &program_args).map(|_| ()) }); + let interact = thread::spawn(move || -> Result<()> { + sub_shell_thread(&program, &program_args).map(|_| ()) + }); clear_screen(); io::stdout().flush().unwrap();