migrated pwd to ansi_term and more modularity

This commit is contained in:
Candifloss 2024-11-27 16:41:55 +05:30
parent 18168cf0e1
commit a0c6f3a71e
5 changed files with 110 additions and 60 deletions

View File

@ -1,5 +1,6 @@
use ansi_term::ANSIGenericString; use ansi_term::ANSIGenericString;
use ansi_term::Colour::RGB; use ansi_term::Colour::RGB;
use std::path::Path;
use std::process::Command; use std::process::Command;
// SSH indicator symbol // SSH indicator symbol
@ -32,6 +33,14 @@ pub fn info() -> Option<(String, String)> {
} }
} }
pub fn repo_name(path: &str) -> String {
Path::new(path)
.file_name()
.and_then(|name| name.to_str())
.unwrap_or("") // Default value if None
.to_string() // Convert &str to String
}
//Git branch indicator //Git branch indicator
pub fn indicator(branch: Option<String>) -> ANSIGenericString<'static, str> { pub fn indicator(branch: Option<String>) -> ANSIGenericString<'static, str> {
match branch { match branch {

View File

@ -1,15 +1,14 @@
use crate::indicators::git::{repo_name, MAIN_COL};
use ansi_term::ANSIGenericString; use ansi_term::ANSIGenericString;
use ansi_term::Colour::RGB; use ansi_term::Colour::RGB;
use std::env::current_dir; use std::env::current_dir;
pub const UNKNOWN_PATH: &str = "\u{2248}"; // "≈" pub const UNKNOWN_PATH: &str = "\u{2248}"; // "≈"
pub const PATH_COL: ansi_term::Colour = RGB(82, 82, 82); pub const PATH_COL: ansi_term::Colour = RGB(82, 82, 82);
pub const REPO_COL: ansi_term::Colour = RGB(55, 120, 130);
fn home_dir() -> String { fn home_dir() -> String {
std::env::var("HOME").map_or_else( std::env::var("HOME").map_or_else(|_| "".to_string(), |path| path.to_string())
|_| "".to_string(),
|path| path.to_string(),
)
} }
fn full_path() -> String { fn full_path() -> String {
@ -19,15 +18,77 @@ fn full_path() -> String {
) )
} }
fn replace_home(path: String) -> String { fn remove_repo(pwd_path: &str, repo_path: &str) -> String {
let homedir = home_dir(); pwd_path.replacen(repo_path, "", 1)
path.replace(&homedir, "~")
} }
pub fn pwd(abbrev_home:bool) -> ANSIGenericString<'static, str> { fn replace_home(path: &str) -> String {
let mut path = full_path(); let homedir = home_dir();
if abbrev_home { path.replacen(&homedir, "~", 1)
path = replace_home(path);
} }
fn short(path: &str, slash_limit: u8) -> String {
let slashes = path.matches('/').count();
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 after "/")
.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("/")
}
}
pub fn pwd(
abbrev_home: bool,
shorten_path: bool,
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 };
if replace_repo && git_repo.is_some() {
if let Some(repo_path) = git_repo {
path = remove_repo(&path, &repo_path);
let repo_name = repo_name(&repo_path);
if shorten_path {
path = short(&path, slash_limit);
}
match path.as_str() {
"" => REPO_COL.paint(repo_name),
_ => format!(
"{}{}{}",
REPO_COL.paint(repo_name),
MAIN_COL.paint(" \u{F02A2} "),
PATH_COL.italic().paint(path)
)
.into(),
}
} else {
PATH_COL.italic().paint(path) PATH_COL.italic().paint(path)
} }
} 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)
}
}

View File

@ -9,8 +9,7 @@ pub const NORMIE_COL: ansi_term::Colour = RGB(0, 255, 180); // A kind of green
//Root user indicator //Root user indicator
pub fn username() -> String { pub fn username() -> String {
var("USER") var("USER").unwrap_or_else(|_| "UnknownUser".to_string())
.unwrap_or_else(|_| "UnknownUser".to_string())
} }
pub fn indicator() -> ANSIGenericString<'static, str> { pub fn indicator() -> ANSIGenericString<'static, str> {

View File

@ -14,33 +14,45 @@ use crate::indicators::user;
fn main() { fn main() {
let cmd_args: Vec<String> = std::env::args().collect(); let cmd_args: Vec<String> = std::env::args().collect();
let mut prompt: String = String::new();
let mut components: Vec<String> = Vec::new();
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;
let indicate_git_branch: bool = true; let indicate_git_branch: bool = true;
let pwd: bool = true; let show_pwd: bool = true;
let abbrev_home: bool = true; let abbrev_home: bool = true;
let shorten_path: bool = true;
let replace_repo: bool = true;
let mut git_info = None;
if pwd {
prompt += &pwd::pwd(abbrev_home).to_string();
}
if indicate_ssh { if indicate_ssh {
prompt += &ssh::indicator().to_string(); components.push(ssh::indicator().to_string());
} }
if indicate_git_branch { if indicate_git_branch {
let git_info = git::info(); git_info = git::info();
match git_info { match git_info {
Some((_repo, branch)) => prompt += &git::indicator(Some(branch)).to_string(), Some(ref info) => components.push(git::indicator(Some(info.1.clone())).to_string()),
None => prompt += &git::indicator(None).to_string(), None => components.push(git::indicator(None).to_string()),
}; }
} }
if indicate_user { if indicate_user {
prompt += &user::indicator().to_string(); components.push(user::indicator().to_string());
} }
if indicate_err { if indicate_err {
prompt += &error::indicator(cmd_args).to_string(); components.push(error::indicator(cmd_args).to_string());
} }
if show_pwd {
let repo_path = match git_info {
Some(info) => Some(info.0), // Clone to avoid ownership issues
None => None,
};
components.insert(
0,
pwd::pwd(abbrev_home, shorten_path, replace_repo, repo_path).to_string(),
);
}
let prompt = components.join("");
print!("{prompt} "); print!("{prompt} ");
} }

View File

@ -1,31 +0,0 @@
use std::env::{args, current_dir, var_os};
pub fn abrev_path(path: &str) -> String {
let mut short_dir = path.to_string();
let slashes = path.matches('/').count();
if slashes > 3 {
let parts: Vec<&str> = path.split('/').collect();
let len = parts.len() - 1;
let mut ch1: String;
for part in &parts[0..len] {
if part.to_string() != "" {
// to avoid the 1st "/"
ch1 = part.chars().next().expect(part).to_string(); // 1st char of each part
short_dir = short_dir.replace(part, &ch1);
}
}
}
short_dir
}
//pwd
pub fn homedir() -> String {
var_os("HOME")
.expect("UnknownDir")
.to_str()
.expect("UnknownDir")
.to_string()
}