diff --git a/src/indicators/git.rs b/src/indicators/git.rs index b70b094..bc5cf99 100644 --- a/src/indicators/git.rs +++ b/src/indicators/git.rs @@ -11,8 +11,8 @@ pub const OTHER_COL: ansi_term::Colour = RGB(82, 82, 82); // pub const NORMIE_COL: ansi_term::Colour = RGB(255, 255, 255); // White pub fn info() -> Option<(String, String)> { - let output = Command::new("git") - .args(["rev-parse", "--show-toplevel", "--abbrev-ref", "HEAD"]) + let output = Command::new("git") // Program/Command to execute + .args(["rev-parse", "--show-toplevel", "--abbrev-ref", "HEAD"]) // Arguments .output() .ok()?; @@ -28,7 +28,7 @@ pub fn info() -> Option<(String, String)> { pub fn repo_name(path: &str) -> String { Path::new(path) - .file_name() // Extracts the last component of the path. + .file_name() // Extracts the last component of the path. .and_then(|name| name.to_str()) // Converts the `OsStr` to `&str`. .unwrap_or("") // Default value(empty string) if None(no valid name) .to_string() // Converts &str to String diff --git a/src/indicators/pwd.rs b/src/indicators/pwd.rs index 11a5c45..691681a 100644 --- a/src/indicators/pwd.rs +++ b/src/indicators/pwd.rs @@ -16,7 +16,7 @@ fn home_dir() -> String { fn full_path() -> String { current_dir().map_or_else( |_| UNKNOWN_PATH.to_string(), - |path| path.to_string_lossy().to_string(), + |path| path.display().to_string(), ) } @@ -27,34 +27,29 @@ fn remove_repo(pwd_path: &str, repo_path: &str) -> String { /// Replace the 'home directory' part of the path with a the '~' symbol fn replace_home(path: &str) -> String { - let homedir = home_dir(); - path.replacen(&homedir, "~", 1) + path.replacen(&home_dir(), "~", 1) } fn short(path: &str, slash_limit: u8) -> String { - let slashes = path.matches('/').count(); + let slashes = path.matches('/').count(); // Get the number of slashes if slashes <= slash_limit.into() { - path.to_string() // Short path, return without changes - } else { - // Long path, shorten it - let parts: Vec<&str> = path.split('/').collect(); // Split the path into parts - let first = if path.starts_with('~') { "~" } else { "" }; // Determine the first part correctly - let last = parts[parts.len() - 1]; // The last part - - // Abbreviate middle parts (take the first character of each) - let abbreviated_middle: Vec = parts[1..parts.len() - 1] // Skip the first and last part - .iter() - .filter(|&&part| !part.is_empty()) // Avoid empty parts (like "//") - .map(|&part| part.chars().next().unwrap().to_string()) // Take the first letter - .collect(); - - // Join the parts back together with "/" and return the shortened path - let mut shortened_path = vec![first.to_string()]; - shortened_path.extend(abbreviated_middle); - shortened_path.push(last.to_string()); - - shortened_path.join("/") + return path.to_string(); // Short path, return without changes } + + // Else: Long path, shorten it + let parts: Vec<&str> = path.split('/').collect(); // Split the path into parts + let first = if path.starts_with('~') { "~" } else { "" }; // Determine the first part correctly + let last = parts[parts.len() - 1]; // The last part + + // Abbreviate middle parts (take the first character of each) + let abbreviated_middle = parts[1..parts.len() - 1] // Skip the first and last part + .iter() + .filter(|&&part| !part.is_empty()) // Avoid empty parts (like "//") + .map(|&part| part.chars().next().unwrap().to_string()) // Take the first letter + .collect::>() // Collect the parts as a Vec + .join("/"); // Join them with a "/" separator + + format!("{first}/{abbreviated_middle}/{last}") // Final } pub fn pwd( @@ -63,9 +58,10 @@ pub fn pwd( replace_repo: bool, git_repo: Option, ) -> ANSIGenericString<'static, str> { - let mut path = full_path(); - let slash_limit: u8 = if replace_repo { 2 } else { 3 }; + let slash_limit: u8 = if replace_repo { 2 } else { 3 }; // Max number of slashes + let mut path = full_path(); // Get the full path of he current directory + // Replace a git repo root path with the repo's name if replace_repo && git_repo.is_some() { if let Some(repo_path) = git_repo { path = remove_repo(&path, &repo_path); @@ -73,26 +69,28 @@ pub fn pwd( if shorten_path { path = short(&path, slash_limit); } - match path.as_str() { - "" => REPO_COL.paint(repo_name), - _ => format!( + return if path.is_empty() { + REPO_COL.paint(repo_name) // In the root dir of the repo + } else { + // In a subdir inside the repo + format!( "{}{}{}", - REPO_COL.paint(repo_name), - MAIN_COL.paint(" \u{F02A2} "), - PATH_COL.italic().paint(path) + REPO_COL.paint(repo_name), // Repo name + MAIN_COL.paint(" \u{F02A2} "), // Seperator + PATH_COL.italic().paint(path) // Sub-directory ) - .into(), - } - } else { - PATH_COL.italic().paint(path) + .into() + }; } - } else if abbrev_home { - path = replace_home(&path); - if shorten_path { - path = short(&path, slash_limit); - } - PATH_COL.italic().paint(path) - } else { - PATH_COL.italic().paint(path) } + + // Replace the home directory path with the 'home symbol': ~ + if abbrev_home { + path = replace_home(&path); + } + if shorten_path { + path = short(&path, slash_limit); + } + + PATH_COL.italic().paint(path) } diff --git a/src/indicators/ssh.rs b/src/indicators/ssh.rs index ef4aae7..0e9bc88 100644 --- a/src/indicators/ssh.rs +++ b/src/indicators/ssh.rs @@ -1,19 +1,22 @@ use ansi_term::ANSIGenericString; use ansi_term::Colour::RGB; -use std::env::var; +use std::env::var; // For environment variables -// SSH indicator symbol -pub const SSH_SYMBOL: &str = "\u{276F}"; // "❯" -pub const SSH_COL: ansi_term::Colour = RGB(255, 149, 0); // A ind of orange -pub const NORMIE_COL: ansi_term::Colour = RGB(255, 255, 255); // White +/// Constants +pub const SSH_SYMBOL: &str = "\u{276F}"; // SSH indicator symbol: "❯" +pub const SSH_COL: ansi_term::Colour = RGB(255, 149, 0); // In SSH session +pub const NORMIE_COL: ansi_term::Colour = RGB(255, 255, 255); // Non-SSH session +const SSH_ENV_VARS: [&str; 2] = ["SSH_TTY", "SSH_CONNECTION"]; // Environment variables normally present in SSH sessions +/// Checks if current session is an SSH session fn is_ssh_session() -> bool { - var("SSH_TTY").is_ok() || var("SSH_CONNECTION").is_ok() + SSH_ENV_VARS.iter().any(|&var_name| var(var_name).is_ok()) // any() iterates through the iter and stops at first `true`. Equal to `||`(`or` condition) } -//SSH shell indicator +/// SSH shell indicator pub fn indicator() -> ANSIGenericString<'static, str> { - if is_ssh_session() { + let is_ssh: bool = is_ssh_session(); + if is_ssh { SSH_COL.paint(SSH_SYMBOL) } else { NORMIE_COL.paint(SSH_SYMBOL) diff --git a/src/indicators/user.rs b/src/indicators/user.rs index 45d380a..3521a58 100644 --- a/src/indicators/user.rs +++ b/src/indicators/user.rs @@ -1,11 +1,11 @@ use ansi_term::ANSIGenericString; use ansi_term::Colour::RGB; -use std::env::var; +use std::env::var; // For environment variables -// User indicator symbol -pub const USER_SYMBOL: &str = "\u{276F}"; // "❯" -pub const ROOT_COL: ansi_term::Colour = RGB(255, 53, 94); // Riot red or something -pub const NORMIE_COL: ansi_term::Colour = RGB(0, 255, 180); // A kind of green +pub const USER_SYMBOL: &str = "\u{276F}"; // User indicator symbol: "❯" +pub const ROOT_COL: ansi_term::Colour = RGB(255, 53, 94); // If the user is root +pub const NORMIE_COL: ansi_term::Colour = RGB(0, 255, 180); // Regular user +const ROOT_USER: &str = "root"; // Root username constant //Root user indicator pub fn username() -> String { @@ -13,7 +13,8 @@ pub fn username() -> String { } pub fn indicator() -> ANSIGenericString<'static, str> { - if username() == "root" { + let user = username(); + if user == ROOT_USER { ROOT_COL.paint(USER_SYMBOL) } else { NORMIE_COL.paint(USER_SYMBOL) diff --git a/src/main.rs b/src/main.rs index 87be1d1..3f1bcc7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -18,6 +18,7 @@ fn main() { let mut components: Vec> = Vec::new(); // The components will be concated into one string + // Hard-coded configuration. This will be replaced by a configuration file in a future version let indicate_user: bool = true; let indicate_ssh: bool = true; let indicate_err: bool = true; @@ -33,6 +34,7 @@ fn main() { None }; + // Conditionally add the parts of the prompt if indicate_ssh { components.push(ssh::indicator()); }