1

I'm trying to set up my prompt to conditionally display whether I am in a git repo, and if so, to display the branch. And I want it color coded, so I have it use some color escape sequences to make it look nice. When I go to print it though, I just get this:

alex@alexslaptop:~/gittest \e[0;35m(git:\e[0;32mmaster\e[0;35m) $

What I expect to see is something like this (except colorized)

alex@alexslaptop:~/gittest (git:master) $

I've narrowed it down to the fact that I have a function in my PS1 variable that I have to run every time, so I have something like this:

PS1=""
PS1+="${COLOR_LIGHT_CYAN}\u"
PS1+="${COLOR_WHITE}@"
PS1+="${COLOR_LIGHT_CYAN}\H"
PS1+="${COLOR_WHITE}:"
PS1+="${COLOR_LIGHT_BLUE}\w "
PS1+="\$(vcs_prompt)" #Notice the backslash before the $
PS1+="${COLOR_NC}\$ "
export PS1

If I remove the backslash on the annotated line, it works, but only once and never updates. If I add it in, it updates, but displays the escape sequences for the colors.

Since vcs_prompt is a nontrivial function I'll give a simplified example that displays the same behavior:

export COLOR_BLUE='\e[0;34m'
export COLOR_RED='\e[0;31m'
function blue {
  echo "${COLOR_BLUE}blue"
}
export PS1="${COLOR_RED}red \$(blue)"

I would expect it to display

red blue

with the words being colored appropriately. Instead I get:

red \e[0;34mblue

Is there a way to get this to behave how I want?

Alex
  • 111
  • 2
  • 1
    @muru are you sure about that dupe? Making the two variables in the function be export COLOR_BLUE=$'\e[0;34m' and export COLOR_RED=$'\e[0;31m' is not enough. Even adding export -f for the function isn't enough (and that isn't mentioned in the dupe). I don't really see how the answer there can be adapted to fit this question. Either I'm missing something obvious (entirely possible) or this is not similar enough to be closed as a dupe. Could you have another look? – terdon Oct 21 '21 at 11:36
  • 1
    @terdon COLOR_BLUE=$'\e[0;34m' is half the solution, and it does set the colour correctly for me. O.o The other half is that the non-printing characters still need to be accounted for using \[ \] in the prompt, or the prompt length calculation will be broken (which in turn breaks backspacing text or navigating history). What ilkkachu suggests - use a function to set some variables, run that function in PROMPT_COMMAND, and use those variables in PS1 instead, will fix both. Another option is to use PROMPT_COMMAND to set PS1, like I do here. – muru Oct 21 '21 at 12:03
  • Dunno. I spent a few minutes (not very long) trying to adapt that answer to this question and I couldn't get it to work. I'm thinking we should reopen and add a specific answer to this issue. @alex, please let us know if the answer to the duplicate is enough for you to figure this out or if you need more details. – terdon Oct 21 '21 at 12:05
  • @terdon for ilkkachu's approach, something like: COLOR_BLUE=$'\e[0;34m'; COLOR_RED=$'\e[0;31m'; PS1='\[${COLOR_RED}\]red \[$blue_color\]$blue_text'; function blue { blue_color=$COLOR_BLUE; blue_text=blue; }; PROMPT_COMMAND=blue – muru Oct 21 '21 at 12:40
  • I ended up using PROMPT_COMMAND=ps1_update and throwing the whole chunk of code that sets PS1 into ps1_update and now it works (this is basically whats described in the askubuntu link). I guess my question is answered, but it would have been nice to be able to answer it here since the other question marked as the dupe doesn't mention that solution, and it feels weird to have to dig in comments to find an answer when that's what the answer section should be for. Either way I have a working solution now, so thanks :) – Alex Oct 21 '21 at 19:21

0 Answers0