98 lines
3.4 KiB
Rust
98 lines
3.4 KiB
Rust
use crate::indicators::git::{repo_name, MAIN_COL};
|
|
use ansi_term::ANSIGenericString;
|
|
use ansi_term::Colour::RGB;
|
|
use std::env::current_dir;
|
|
|
|
pub const UNKNOWN_PATH: &str = "\u{2248}"; // "≈"
|
|
pub const PATH_COL: ansi_term::Colour = RGB(82, 82, 82);
|
|
pub const REPO_COL: ansi_term::Colour = RGB(55, 120, 130);
|
|
|
|
/// Find the current user's home directory.
|
|
fn home_dir() -> String {
|
|
std::env::var("HOME").map_or_else(|_| String::new(), |path| path.to_string())
|
|
}
|
|
|
|
/// Returns the full path of the current directory as a string.
|
|
fn full_path() -> String {
|
|
current_dir().map_or_else(
|
|
|_| UNKNOWN_PATH.to_string(),
|
|
|path| path.display().to_string(),
|
|
)
|
|
}
|
|
|
|
/// Remove the path of the repo's root from the path, to replace it with the repo's name.
|
|
fn remove_repo(pwd_path: &str, repo_path: &str) -> String {
|
|
pwd_path.replacen(repo_path, "", 1)
|
|
}
|
|
|
|
/// Replace the 'home directory' part of the path with a the '~' symbol
|
|
fn replace_home(path: &str) -> String {
|
|
path.replacen(&home_dir(), "~", 1)
|
|
}
|
|
|
|
fn short(path: &str, slash_limit: u8) -> String {
|
|
let slashes = path.matches('/').count(); // Get the number of slashes
|
|
if slashes <= slash_limit.into() {
|
|
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(
|
|
abbrev_home: bool,
|
|
shorten_path: bool,
|
|
replace_repo: bool,
|
|
git_repo: Option<String>,
|
|
) -> ANSIGenericString<'static, str> {
|
|
let mut slash_limit: u8 = 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);
|
|
let repo_name = repo_name(&repo_path);
|
|
if shorten_path {
|
|
slash_limit = 2; // Max number of slashes
|
|
path = short(&path, slash_limit);
|
|
}
|
|
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), // Repo name
|
|
MAIN_COL.paint(" \u{F02A2} "), // Seperator
|
|
PATH_COL.italic().paint(path) // Sub-directory
|
|
)
|
|
.into()
|
|
};
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
}
|