0

my .bashrc:

export COLOR_RST=$(tput sgr0)
export COLOR_WHI=$(tput setaf 15)$(tput bold)
export COLOR_gra=$(tput setaf 7)
export COLOR_GRA=$(tput setaf 8)$(tput bold)
export COLOR_BLK=$(tput setaf 16)$(tput bold)
export COLOR_red=$(tput setaf 1)
export COLOR_RED=$(tput setaf 9)$(tput bold)
export COLOR_grn=$(tput setaf 2)
export COLOR_GRN=$(tput setaf 10)$(tput bold)
export COLOR_yel=$(tput setaf 3)
export COLOR_YEL=$(tput setaf 11)$(tput bold)
export COLOR_blu=$(tput setaf 4)
export COLOR_BLU=$(tput setaf 12)$(tput bold)
export COLOR_pur=$(tput setaf 5)
export COLOR_PUR=$(tput setaf 13)$(tput bold)
export COLOR_cya=$(tput setaf 6)
export COLOR_CYA=$(tput setaf 14)$(tput bold)

git_branch_info () {
    local _bra="$(git branch 2> /dev/null | grep -e ^* | cut -d\  -f2)"
    local status_por="$(git status --porcelain 2>/dev/null)"
    local _mod="±$(echo -e "$status_por" | grep -E '^( M|M |MM)' | wc -l)"
    local _add="+$(echo -e "$status_por" | grep -E '^( A|A |AA)' | wc -l)"
    local _del="-$(echo -e "$status_por" | grep -E '^( D|D |DD)' | wc -l)"
    local _ren="r$(echo -e "$status_por" | grep -E '^( R|R |RR)' | wc -l)"
    local _unt="?$(echo -e "$status_por" | grep -E '^\?\?' | wc -l)"

    # echo "b=$_bra:m=$_mod:a=$_add:d=$_del:r=$_ren:"
    [[ "$_bra" = '' ]]   && _bra="" || _bra=" ${COLOR_PUR}$_bra"
    [[ "$_mod" = '±0' ]] && _mod="" || _mod=" ${COLOR_YEL}$_mod"
    [[ "$_add" = '+0' ]] && _add="" || _add=" ${COLOR_GRN}$_add"
    [[ "$_del" = '-0' ]] && _del="" || _del=" ${COLOR_RED}$_del"
    [[ "$_ren" = 'r0' ]] && _ren="" || _ren=" ${COLOR_YEL}$_ren"
    [[ "$_unt" = '?0' ]] && _unt="" || _unt=" ${COLOR_GRN}$_unt"

    echo -e "$_bra$_mod$_add$_del$_ren$_unt${COLOR_RST}"

}

color_prompt () {
    if [[ "$USER" = "root" ]]; then
        local lv_col="${COLOR_RED}"
        local lv_sym="#"
    else
        local lv_col="${COLOR_GRN}"
        local lv_sym="$"
    fi

    local usr_host="${lv_col}${USER}${COLOR_GRA}@${COLOR_BLU}\h${COLOR_GRA}:${COLOR_RST}"
    local time="$COLOR_WHI\d \t${COLOR_RST}"
    local curr_path="${COLOR_blu}\w${COLOR_RST}"
    local git='$(git_branch_info)'
    local prompt="${lv_col}${lv_sym} ${COLOR_RST}"

    export PS1="\n$time\n${usr_host}${curr_path}${git}\n${prompt}"
    export PS2="${lv_col}>${COLOR_RST}  "
}
color_prompt

It works as expected (I get a prompt with three lines, clock, path, and command prompt. The colors look ok.

But when, after typing a command, I hit C-a (to return to the beginning of the line) then the cursor doesn't go all the way to the left: Part of the command gets "stuck" at the beginning, and extra empty space is concatenated at the end of the prompt. It is like the cursor loses track of where the command is, and believes it is shifted to the right. Basically, the cursor makes no sense and I need to C-c in order to re-draw the prompt.

Reading Bash: PS1 vs Prompt Command to set prompt and title I got even more confused whether the PS1 edition approach is right.

What could be causing the bug?

4
  • Duplicates: superuser.com/search?q=ps1+001+002 Commented Jun 23, 2023 at 11:26
  • 1
    Give it a look here in particular for the last prompt character and the way to store the color values...
    – Hastur
    Commented Jun 23, 2023 at 13:28
  • @LPChip is it a sarcastic comment? unix.stackexchange.com/questions/32096/…
    – onlycparra
    Commented Jun 24, 2023 at 23:15
  • 1
    @onlycparra no, it wasn't. It was my lack of knowing that this is a unix thing. ps1 is also the extension of a powershell script. I've removed my comment.
    – LPChip
    Commented Jun 25, 2023 at 11:07

1 Answer 1

0

Open a terminal, type
$ man bash
... hit Enter.

In this situation you have less displaying the bash "man page".
If you hit h you will see terse help on the available keys. q to quit help.

In the help you will find / to be for initiating a search on a pattern (regexp!). Therefore:

/^PROMPTING will take you to the portion of the man page telling about specialties (escapes!) that can be used in the PS0 to PS4 prompts.

In there take note of \[ and \] escapes;
these will tell bash that you're including non-printing things, enclosing any escapes (e.g. color changes) between these two, will make prompting work the way you'd expect.

2
  • 1
    What the manual page doesn't mention is that \[ and \] get translated to \001 and \002 internally... but if you use $() inside your PS1, like OP does, an \[ that's output by the function won't get translated correctly, so the function must directly output an actual \001 byte instead. Commented Jun 24, 2023 at 17:52
  • So, should I include the \001 and \002 on the color definitions themselves? I jusd did COLOR_XYZ=$'\001'$(tput ...)$'\002', and it seems to work.
    – onlycparra
    Commented Jun 24, 2023 at 23:13

Not the answer you're looking for? Browse other questions tagged .