0

I have been trying to customize my bash prompt

below is my config

#!bin/bash
Nocolor="\[\033[0m\]"       # Text Reset

# Bold High Intensty
BIBlack="\[\033[1;90m\]"      # Black
BIRed="\[\033[1;91m\]"        # Red
BIGreen="\[\033[1;92m\]"      # Green
BIYellow="\[\033[1;93m\]"     # Yellow
BIBlue="\[\033[1;94m\]"       # Blue
BIPurple="\[\033[1;95m\]"     # Purple
BICyan="\[\033[1;96m\]"       # Cyan
BIWhite="\[\033[1;97m\]"      # White

function git_color {
  local git_status="$(git status 2> /dev/null)"

  if [[ $git_status =~ "Changes not staged for commit" ]]; then
    echo -e $BIRed
  elif [[ $git_status =~ "Changes to be committed" ]]; then
    echo -e $BIYellow
  else
    echo -e $BIGreen
  fi  
}

PS1="\u\[$BIRed\]\W"
PS1+="\$(git_color) $ " 
PS1+="\[$Nocolor\]"

export PS1

What I'm trying to do is highlight my $ symbol with specific colors based on my git status

After these my prompt looks like this enter image description here

Where does this \[\] comes from. I tried all possible ways to call the method git_status but nothing works.

My Bash Version

bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

Help me out. Thanks in advance.

Subi
  • 25
  • I'm pretty sure the command \$(git_color) prints the character. I am not sure how to avoid it – Subi Jan 25 '20 at 11:30

2 Answers2

1

Don't include the \[ or \] anywhere else then directly in the PS1 so you don't have to track what gets expanded and interpreted where.

Nocolor="\033[0m"       # Text Reset

# Bold High Intensty
BIBlack="\033[1;90m"      # Black
BIRed="\033[1;91m"        # Red
BIGreen="\033[1;92m"      # Green
BIYellow="\033[1;93m"     # Yellow
BIBlue="\033[1;94m"       # Blue
BIPurple="\033[1;95m"     # Purple
BICyan="\033[1;96m"       # Cyan
BIWhite="\033[1;97m"      # White

function git_color {
  local git_status="$(git status 2> /dev/null)"

  if [[ $git_status =~ "Changes not staged for commit" ]]; then
    echo -ne "$BIRed"
  elif [[ $git_status =~ "Changes to be committed" ]]; then
    echo -ne "$BIYellow"
  else
    echo -ne "$BIGreen"
  fi  
}

PS1="\u\[$BIRed\]\W"
PS1+="\[\$(git_color)\] $ " 
PS1+="\[$Nocolor\]"

I also added -n to echos, but it shouldn't make a differenct.

choroba
  • 47,233
  • Of course, tput setaf is more versatile than hardwired control sequences, printf is better than echo and tput is better yet than either in this case, and SGR 0 is a little drastic when SGR 39 and SGR 22 will suffice. – JdeBP Jan 26 '20 at 01:20
0

Somebody have posted an answer to remove the \[\] from color code. Later he/she have removed the answer. Thanks for you suggestion it worked

I've changed "\[\033[0m\]" to "\033[0m"

It worked. Thanks for your answer

Subi
  • 25
  • It doesn't work, it calculates the length of the prompt wrong. Try listing the history. – choroba Jan 25 '20 at 11:48
  • Of course, this then reveals a bug in your git_color function. https://unix.stackexchange.com/a/317743/5132 – JdeBP Jan 25 '20 at 11:49