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