Improved efficiency & best practices, & comments

This commit is contained in:
Candifloss 2024-11-30 11:31:50 +05:30
parent 309021fb68
commit 82528f13be
5 changed files with 65 additions and 61 deletions

View File

@ -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 const NORMIE_COL: ansi_term::Colour = RGB(255, 255, 255); // White
pub fn info() -> Option<(String, String)> { pub fn info() -> Option<(String, String)> {
let output = Command::new("git") let output = Command::new("git") // Program/Command to execute
.args(["rev-parse", "--show-toplevel", "--abbrev-ref", "HEAD"]) .args(["rev-parse", "--show-toplevel", "--abbrev-ref", "HEAD"]) // Arguments
.output() .output()
.ok()?; .ok()?;

View File

@ -16,7 +16,7 @@ fn home_dir() -> String {
fn full_path() -> String { fn full_path() -> String {
current_dir().map_or_else( current_dir().map_or_else(
|_| UNKNOWN_PATH.to_string(), |_| 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 /// Replace the 'home directory' part of the path with a the '~' symbol
fn replace_home(path: &str) -> String { fn replace_home(path: &str) -> String {
let homedir = home_dir(); path.replacen(&home_dir(), "~", 1)
path.replacen(&homedir, "~", 1)
} }
fn short(path: &str, slash_limit: u8) -> String { 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() { if slashes <= slash_limit.into() {
path.to_string() // Short path, return without changes return path.to_string(); // Short path, return without changes
} else { }
// Long path, shorten it
// Else: Long path, shorten it
let parts: Vec<&str> = path.split('/').collect(); // Split the path into parts 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 first = if path.starts_with('~') { "~" } else { "" }; // Determine the first part correctly
let last = parts[parts.len() - 1]; // The last part let last = parts[parts.len() - 1]; // The last part
// Abbreviate middle parts (take the first character of each) // Abbreviate middle parts (take the first character of each)
let abbreviated_middle: Vec<String> = parts[1..parts.len() - 1] // Skip the first and last part let abbreviated_middle = parts[1..parts.len() - 1] // Skip the first and last part
.iter() .iter()
.filter(|&&part| !part.is_empty()) // Avoid empty parts (like "//") .filter(|&&part| !part.is_empty()) // Avoid empty parts (like "//")
.map(|&part| part.chars().next().unwrap().to_string()) // Take the first letter .map(|&part| part.chars().next().unwrap().to_string()) // Take the first letter
.collect(); .collect::<Vec<_>>() // Collect the parts as a Vec
.join("/"); // Join them with a "/" separator
// Join the parts back together with "/" and return the shortened path format!("{first}/{abbreviated_middle}/{last}") // Final
let mut shortened_path = vec![first.to_string()];
shortened_path.extend(abbreviated_middle);
shortened_path.push(last.to_string());
shortened_path.join("/")
}
} }
pub fn pwd( pub fn pwd(
@ -63,9 +58,10 @@ pub fn pwd(
replace_repo: bool, replace_repo: bool,
git_repo: Option<String>, git_repo: Option<String>,
) -> ANSIGenericString<'static, str> { ) -> ANSIGenericString<'static, str> {
let mut path = full_path(); let slash_limit: u8 = if replace_repo { 2 } else { 3 }; // Max number of slashes
let slash_limit: u8 = if replace_repo { 2 } else { 3 }; 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 replace_repo && git_repo.is_some() {
if let Some(repo_path) = git_repo { if let Some(repo_path) = git_repo {
path = remove_repo(&path, &repo_path); path = remove_repo(&path, &repo_path);
@ -73,26 +69,28 @@ pub fn pwd(
if shorten_path { if shorten_path {
path = short(&path, slash_limit); path = short(&path, slash_limit);
} }
match path.as_str() { return if path.is_empty() {
"" => REPO_COL.paint(repo_name), REPO_COL.paint(repo_name) // In the root dir of the repo
_ => format!(
"{}{}{}",
REPO_COL.paint(repo_name),
MAIN_COL.paint(" \u{F02A2} "),
PATH_COL.italic().paint(path)
)
.into(),
}
} else { } else {
PATH_COL.italic().paint(path) // In a subdir inside the repo
format!(
"{}{}{}",
REPO_COL.paint(repo_name), // Repo name
MAIN_COL.paint(" \u{F02A2} "), // Seperator
PATH_COL.italic().paint(path) // Sub-directory
)
.into()
};
} }
} else if abbrev_home { }
// Replace the home directory path with the 'home symbol': ~
if abbrev_home {
path = replace_home(&path); path = replace_home(&path);
}
if shorten_path { if shorten_path {
path = short(&path, slash_limit); path = short(&path, slash_limit);
} }
PATH_COL.italic().paint(path)
} else {
PATH_COL.italic().paint(path) PATH_COL.italic().paint(path)
} }
}

View File

@ -1,19 +1,22 @@
use ansi_term::ANSIGenericString; use ansi_term::ANSIGenericString;
use ansi_term::Colour::RGB; use ansi_term::Colour::RGB;
use std::env::var; use std::env::var; // For environment variables
// SSH indicator symbol /// Constants
pub const SSH_SYMBOL: &str = "\u{276F}"; // "" pub const SSH_SYMBOL: &str = "\u{276F}"; // SSH indicator symbol: ""
pub const SSH_COL: ansi_term::Colour = RGB(255, 149, 0); // A ind of orange 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); // White 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 { 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> { 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) SSH_COL.paint(SSH_SYMBOL)
} else { } else {
NORMIE_COL.paint(SSH_SYMBOL) NORMIE_COL.paint(SSH_SYMBOL)

View File

@ -1,11 +1,11 @@
use ansi_term::ANSIGenericString; use ansi_term::ANSIGenericString;
use ansi_term::Colour::RGB; 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}"; // User indicator symbol: ""
pub const USER_SYMBOL: &str = "\u{276F}"; // "" pub const ROOT_COL: ansi_term::Colour = RGB(255, 53, 94); // If the user is root
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); // Regular user
pub const NORMIE_COL: ansi_term::Colour = RGB(0, 255, 180); // A kind of green const ROOT_USER: &str = "root"; // Root username constant
//Root user indicator //Root user indicator
pub fn username() -> String { pub fn username() -> String {
@ -13,7 +13,8 @@ pub fn username() -> String {
} }
pub fn indicator() -> ANSIGenericString<'static, str> { pub fn indicator() -> ANSIGenericString<'static, str> {
if username() == "root" { let user = username();
if user == ROOT_USER {
ROOT_COL.paint(USER_SYMBOL) ROOT_COL.paint(USER_SYMBOL)
} else { } else {
NORMIE_COL.paint(USER_SYMBOL) NORMIE_COL.paint(USER_SYMBOL)

View File

@ -18,6 +18,7 @@ fn main() {
let mut components: Vec<ANSIGenericString<'static, str>> = Vec::new(); // The components will be concated into one string let mut components: Vec<ANSIGenericString<'static, str>> = 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_user: bool = true;
let indicate_ssh: bool = true; let indicate_ssh: bool = true;
let indicate_err: bool = true; let indicate_err: bool = true;
@ -33,6 +34,7 @@ fn main() {
None None
}; };
// Conditionally add the parts of the prompt
if indicate_ssh { if indicate_ssh {
components.push(ssh::indicator()); components.push(ssh::indicator());
} }