From 3ccf9a25238d984d199ca5b04fabc259313dbc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 28 Jan 2025 21:06:20 -0700 Subject: [PATCH 1/3] Implement prompt templating support via $PS1 This is just an initial support, so far only two templates are supported, using a custom format. Later, we should use some templating engine, and consider compatibility with either Bash or with Zsh. Fixes #200. --- crates/shell/src/main.rs | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs index f8942e2..d836a75 100644 --- a/crates/shell/src/main.rs +++ b/crates/shell/src/main.rs @@ -1,3 +1,4 @@ +use std::env; use std::path::Path; use std::path::PathBuf; @@ -54,6 +55,11 @@ async fn interactive(state: Option, norc: bool) -> miette::Result<() let helper = helper::ShellPromptHelper::default(); rl.set_helper(Some(helper)); + // Default PS1 template + let default_ps1 = "{display_cwd}{git_branch}$ "; + // Set the PS1 environment variable + env::set_var("PS1", default_ps1); + let mut state = state.unwrap_or_else(init_state); let home = dirs::home_dir().ok_or(miette::miette!("Couldn't get home directory"))?; @@ -108,14 +114,24 @@ async fn interactive(state: Option, norc: bool) -> miette::Result<() git_branch = "(".to_owned() + &git_branch + ")"; } - let display_cwd = if let Some(stripped) = cwd.strip_prefix(home_str) { + let mut display_cwd = if let Some(stripped) = cwd.strip_prefix(home_str) { format!("~{}", stripped.replace('\\', "/")) } else { cwd.to_string() }; - let prompt = format!("{}{git_branch}$ ", display_cwd); - let color_prompt = format!("\x1b[34m{}\x1b[32m{git_branch}\x1b[0m$ ", display_cwd); + // Read the PS1 environment variable + let ps1 = env::var("PS1").unwrap_or_else(|_| "".to_string()); + + fn replace_placeholders(ps1: &str, display_cwd: &str, git_branch: &str) -> String { + ps1.replace("{display_cwd}", display_cwd) + .replace("{git_branch}", git_branch) + } + + let prompt = replace_placeholders(&ps1, &display_cwd, &git_branch); + display_cwd = format!("\x1b[34m{display_cwd}\x1b[0m"); + git_branch = format!("\x1b[32m{git_branch}\x1b[0m"); + let color_prompt = replace_placeholders(&ps1, &display_cwd, &git_branch); rl.helper_mut().unwrap().colored_prompt = color_prompt; rl.readline(&prompt) }; From 086c75aa062e4c068ec9b4c7d9db8945f4421fe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 28 Jan 2025 22:39:02 -0700 Subject: [PATCH 2/3] Use env_vars instead of the environment variables --- crates/shell/src/main.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs index d836a75..b0aae86 100644 --- a/crates/shell/src/main.rs +++ b/crates/shell/src/main.rs @@ -1,4 +1,4 @@ -use std::env; +use std::collections::HashMap; use std::path::Path; use std::path::PathBuf; @@ -34,7 +34,9 @@ struct Options { } fn init_state() -> ShellState { - let env_vars = std::env::vars().collect(); + let mut env_vars: HashMap = std::env::vars().collect(); + let default_ps1 = "{display_cwd}{git_branch}$ "; + env_vars.insert("PS1".to_string(), default_ps1.to_string()); let cwd = std::env::current_dir().unwrap(); ShellState::new(env_vars, &cwd, commands::get_commands()) } @@ -55,11 +57,6 @@ async fn interactive(state: Option, norc: bool) -> miette::Result<() let helper = helper::ShellPromptHelper::default(); rl.set_helper(Some(helper)); - // Default PS1 template - let default_ps1 = "{display_cwd}{git_branch}$ "; - // Set the PS1 environment variable - env::set_var("PS1", default_ps1); - let mut state = state.unwrap_or_else(init_state); let home = dirs::home_dir().ok_or(miette::miette!("Couldn't get home directory"))?; @@ -121,7 +118,7 @@ async fn interactive(state: Option, norc: bool) -> miette::Result<() }; // Read the PS1 environment variable - let ps1 = env::var("PS1").unwrap_or_else(|_| "".to_string()); + let ps1 = state.env_vars().get("PS1").map_or("", |v| v); fn replace_placeholders(ps1: &str, display_cwd: &str, git_branch: &str) -> String { ps1.replace("{display_cwd}", display_cwd) From 51c226ae67907a4e477611843b590d9c041b7d4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20=C4=8Cert=C3=ADk?= Date: Tue, 28 Jan 2025 22:49:48 -0700 Subject: [PATCH 3/3] Fix a warning --- crates/shell/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/shell/src/main.rs b/crates/shell/src/main.rs index b0aae86..e978ad5 100644 --- a/crates/shell/src/main.rs +++ b/crates/shell/src/main.rs @@ -125,10 +125,10 @@ async fn interactive(state: Option, norc: bool) -> miette::Result<() .replace("{git_branch}", git_branch) } - let prompt = replace_placeholders(&ps1, &display_cwd, &git_branch); + let prompt = replace_placeholders(ps1, &display_cwd, &git_branch); display_cwd = format!("\x1b[34m{display_cwd}\x1b[0m"); git_branch = format!("\x1b[32m{git_branch}\x1b[0m"); - let color_prompt = replace_placeholders(&ps1, &display_cwd, &git_branch); + let color_prompt = replace_placeholders(ps1, &display_cwd, &git_branch); rl.helper_mut().unwrap().colored_prompt = color_prompt; rl.readline(&prompt) };