use std::env::{current_dir,var_os,args}; use colored::{Colorize,ColoredString}; use std::process::Command; fn get_shell_char (shell: String) -> String { let shell_char = match shell.as_str() { "bash" | "/bin/bash" | "/usr/bin/bash" => " ", "zsh" | "/bin/zsh" | "/usr/bin/zsh" | "-zsh" => "󰰶 ", "fish" => "󰈺 ", "nushell" => " ", "ion" => " ", "oursh" => "󱢇 ", _ => "󱆃 ", }; shell_char.to_string() } fn get_git_branch () -> String { let git_status_cmd = Command::new("git") .arg("status") .output() .expect("git_status_cmd_fail"); let git_status_output = String::from_utf8_lossy(&git_status_cmd.stdout); let git_err = String::from_utf8_lossy(&git_status_cmd.stderr); if git_err == "" { git_status_output.split("\n").collect::>()[0] .split(" ").collect::>()[2].to_string() } else { "".to_string() } } fn get_git_root () -> String { let git_repo_root_cmd = Command::new("git") .arg("rev-parse") .arg("--show-toplevel") .output() .expect("git_repo_root_cmd_fail"); let mut git_repo_path = String::from_utf8_lossy(&git_repo_root_cmd.stdout).to_string(); let git_repo_err = String::from_utf8_lossy(&git_repo_root_cmd.stderr); if git_repo_err == "" { let len = git_repo_path.trim_end_matches(&['\r', '\n'][..]).len(); git_repo_path.truncate(len); } else { git_repo_path = "".to_string(); } git_repo_path } fn get_git_repo_name (git_repo_root: String) -> String { let repo_path_split: Vec<&str> = git_repo_root.split("/").collect(); let last_index = repo_path_split.len() - 1; let git_repo_name = repo_path_split[last_index]; git_repo_name.to_string() } fn get_git_char (git_branch: String) -> ColoredString { match git_branch.as_str() { "" => "".clear(), "main" => " 󰊢 ".truecolor(178,98,44), "master" => " 󰊢 ".truecolor(196,132,29), _ => " 󰊢 ".truecolor(82,82,82), } } fn abrev_path (path: String) -> String { let mut short_dir = path.clone(); 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 } fn main() -> std::io::Result<()> { let angle = "❯"; //Root user indicator let user = var_os("USER").expect("UnknownUser").to_str().expect("UnknownUser").to_string(); let mut err: String = "".to_string(); let args: Vec = args().collect(); let shell: String; if args.len() > 1 { shell = args[1].clone(); // Shell symbol if args.len() > 2 { err = args[2].clone(); // Error status } } else { shell = "none".to_string(); } let root_indicator = match user.as_str() { "root" => angle.truecolor(255, 53, 94), _ => angle.truecolor(0, 255, 180), }; let err_indicator = match err.as_str() { "0" => angle.truecolor(0, 255, 180), _ => angle.truecolor(255, 53, 94), }; //SSH shell indicator let ssh_char:ColoredString; match var_os("SSH_TTY") { Some(_val) => { ssh_char = " ".truecolor(0,150,180); }, None => { ssh_char = "".clear(); } } //Git status let git_branch = get_git_branch(); let git_repo_root = get_git_root(); let git_repo_name = get_git_repo_name(git_repo_root.clone()).truecolor(122, 68, 24); let git_char = get_git_char(git_branch); //pwd let homedir = var_os("HOME").expect("UnknownDir").to_str().expect("UnknownDir").to_string(); let pwd = current_dir()?; let mut cur_dir = pwd.display().to_string(); cur_dir = cur_dir.replace(&git_repo_root, ""); // Remove git repo root cur_dir = cur_dir.replace(&homedir, "~"); // Abreviate homedir with "~" cur_dir = abrev_path(cur_dir); print!("{}{}{}{}{}{}{} ", ssh_char, get_shell_char(shell).truecolor(75,75,75), git_repo_name, git_char, cur_dir.italic().truecolor(82,82,82), root_indicator, err_indicator, ); Ok(()) }