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 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

View File

@ -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<String> = 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::<Vec<_>>() // 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<String>,
) -> 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)
}

View File

@ -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)

View File

@ -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)

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
// 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());
}