Reputation: 339
I'm trying to set my bash prompt to with the following script. Everything works, but the part where I print out the branch name in a Git repository and the status of the branch in color. The colors are somewhat arbitrary, but needless to say it would be red if any files are uncommitted, or yellow if files are unstaged, and green for anything else. It's printing out the part i want in white thought. When I run the part of the script where, towards the end, I define $branchStyle
individually, it works, but its not within here. What am I doing wrong?
prompt_git() {
local s=""
local branchName=""
# check if the current directory is in a git repository
if [ $(git rev-parse --is-inside-work-tree &>/dev/null; printf "%s" $?) == 0 ]; then
# check if the current directory is in .git before running git checks
if [ "$(git rev-parse --is-inside-git-dir 2> /dev/null)" == "false" ]; then
# ensure index is up to date
git update-index --really-refresh -q &>/dev/null
# check for uncommitted changes in the index
if ! $(git diff --quiet --ignore-submodules --cached); then
s="$s+";
fi
# check for unstaged changes
if ! $(git diff-files --quiet --ignore-submodules --); then
s="$s!";
fi
# check for untracked files
if [ -n "$(git ls-files --others --exclude-standard)" ]; then
s="$s?";
fi
# check for stashed files
if $(git rev-parse --verify refs/stash &>/dev/null); then
s="$s$";
fi
fi
# get the short symbolic ref
# if HEAD isn't a symbolic ref, get the short SHA
# otherwise, just give up
branchName="$(git symbolic-ref --quiet --short HEAD 2> /dev/null || \
git rev-parse --short HEAD 2> /dev/null || \
printf "(unknown)")"
[ -n "$s" ] && s=" [$s]"
printf "%s" "$1$branchName$s"
else
return
fi
}
set_prompts() {
local bold=$(tput bold)
local reset=$(tput sgr0)
local base05=$(tput setaf 188) # light grey
local base08=$(tput setaf 210) # red
local base0A=$(tput setaf 221) # yellow
local base0B=$(tput setaf 114) # green
if git rev-parse --git-dir >/dev/null 2>&1; then
# check for uncommitted changes in the index
if ! git diff-index --quiet --cached HEAD --ignore-submodules -- >&2; then
branchStyle=$base08
# check for unstaged changes
elif ! git diff-files --quiet --ignore-submodules -- >&2; then
branchStyle=$base0A
else
branchStyle=$base0B
fi
fi
PS1+="\$(prompt_git \"$bold$base05 on $branchStyle\")" # git repository details
export PS1
}
set_prompts
unset set_prompts
Upvotes: 3
Views: 2180
Reputation: 123690
A good approach to any problem is to reduce it to the minimal piece of code required to reproduce the issue you are seeing. This makes it easier to debug, easier for others to read and solve, and makes for a more general question that other users can benefit from.
For example, if you look into your problem, you'll see that:
Now we can write a question with a small code sample that shows exactly what's wrong:
I expected the following piece of code to show "in /tmp" when I
cd /tmp
, but instead the prompt remains blank. Why doesn't it update?
set_prompts() {
message=""
if [[ $PWD/ == /tmp/* ]]
then
message="in /tmp"
fi
PS1="\$(echo $message) \$"
}
set_prompts
unset set_prompts
This question is significantly easier to read and answer: set_prompts
runs once and calculates a value for $message
, and then it's unset and never executed again. This is why the message never changes.
To make it work, make sure to re-run it before every prompt to regenerate it. This can be done with PROMPT_COMMAND
:
set_prompts() {
PS1='\u@\h:\w ' # <-- Reset PS1 before each run
message=""
if [[ $PWD/ == /tmp/* ]]
then
message="in /tmp"
fi
PS1="\$(echo $message) \$"
}
PROMPT_COMMAND='set_prompts' # <-- Run function before every prompt
This works as expected, and can be easily adapted to your actual, long piece of code.
Upvotes: 3
Reputation: 3540
Not all terminals seem to support the 3 digit numbers, but some are restricted to the portable 8 colors declared in man terminfo:
Color #define Value RGB
black COLOR_BLACK 0 0, 0, 0
red COLOR_RED 1 max,0,0
green COLOR_GREEN 2 0,max,0
yellow COLOR_YELLOW 3 max,max,0
blue COLOR_BLUE 4 0,0,max
magenta COLOR_MAGENTA 5 max,0,max
cyan COLOR_CYAN 6 0,max,max
white COLOR_WHITE 7 max,max,max
So, I think your problem is the use of the higher color numbers. You can output a color table for your terminal like this:
( x=`tput op` y=`printf %$((${COLUMNS}-6))s`;for i in {0..256};do o=00$i;echo -e ${o:${#o}-3:3} `tput setaf $i;tput setab $i`${y// /=}$x;done; )
Upvotes: 1