Skip to main content
Code Review

Return to Question

deleted 7 characters in body
Source Link
toolic
  • 15.1k
  • 5
  • 29
  • 211

It can work in zsh, too, but I couldn't figure out the zsh equivalent of bash's $PROMPT_COMMAND to add to the zsh config file(precmd() didn't work).
I haven't tested in other shells, but I guess it works.
Here's as screenshot(pls ignoreignore the zsh prompt):

PS: Here's my repo

It can work in zsh, too, but I couldn't figure out the zsh equivalent of bash's $PROMPT_COMMAND to add to the zsh config file(precmd() didn't work).
I haven't tested in other shells, but I guess it works.
Here's as screenshot(pls ignore the zsh prompt):

PS: Here's my repo

It can work in zsh, too, but I couldn't figure out the zsh equivalent of bash's $PROMPT_COMMAND to add to the zsh config file(precmd() didn't work).
I haven't tested in other shells, but I guess it works.
Here's as screenshot(ignore the zsh prompt):

Here's my repo

added 77 characters in body
Source Link

PS: Here's my repo

PS: Here's my repo

Source Link

Rust code to print shell prompt

I'm new to Rust, and this is my first successful significant Rust code. It prints a prompt(which is technically a string) to the console.
I'm struggling with concepts like ownership in Rust, so, some code review and advice might be of great help.

Current features:

  • Symbol indicating the current identified shell
  • Root user indicator(color)
  • Error status(color)
  • SSH session indicator
  • Git repo indicator, branch indicator(color), repo name
  • pwd(abbreviated when needed)

Known Issues:

  • I could'nt get the Error Status indicator to work as expected(red on err, green on success)

Here's the code:

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"
 => " ",
 "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::<Vec<&str>>()[0]
 .split(" ").collect::<Vec<&str>>()[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<String> = 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(())
}

It was successfully tested in bash by adding this to the bashrc:

export PS1=""
PROMPT_COMMAND="/path/to/my/binary 0ドル $?"

It can work in zsh, too, but I couldn't figure out the zsh equivalent of bash's $PROMPT_COMMAND to add to the zsh config file(precmd() didn't work).
I haven't tested in other shells, but I guess it works.
Here's as screenshot(pls ignore the zsh prompt):

Screenshot

lang-rust

AltStyle によって変換されたページ (->オリジナル) /