2

I have a really annoying problem. I have followed all of the protocol for making a bash PS1. I know about surrounding non-printable characters with \[ and \] or \001 and \002; however, I have a problem with text that comes after where the cursor is. When you press backspace, it all disappears.

Take a look at the bash PS1 (making it your bashrc and testing might be useful -- be sure to save a copy of YOUR bashrc):

## GRML
# grml battery?
GRML_DISPLAY_BATTERY=1

# battery dir
if [ -d /sys/class/power_supply/BAT0 ]; then
    _PS1_bat_dir='BAT0';
else
    _PS1_bat_dir='BAT1';
fi

# ps1 return and battery
_PS1_ret(){
    # should be at beg of line (otherwise more complex stuff needed)
    RET=$?;

    # battery
    if [[ "$GRML_DISPLAY_BATTERY" == "1" ]]; then
        if [ -d /sys/class/power_supply/$_PS1_bat_dir ]; then
            # linux
            STATUS="$( cat /sys/class/power_supply/$_PS1_bat_dir/status )";
            if [ "$STATUS" = "Discharging" ]; then
                bat=$( printf ' v%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Charging" ]; then
                bat=$( printf ' ^%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            elif [ "$STATUS" = "Full" ] || [ "$STATUS" = "Unknown" ] && [ "$(cat /sys/class/power_supply/$_PS1_bat_dir/capacity)" -gt "98" ]; then
                bat=$( printf ' =%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            else
                bat=$( printf ' ?%d%%' "$( cat /sys/class/power_supply/$_PS1_bat_dir/capacity )" );
            fi;
        fi
    fi

    if [[ "$RET" -ne "0" ]]; then
        printf '\001%*s%s\r%s\002%s ' "$(tput cols)" ":( $bat " "[0;31;1m" "$RET"
    else
        printf '\001%*s%s\r\002' "$(tput cols)" "$bat "
    fi;
}

# ps1 git branch
_PS1_git(){
    if ! type 'git' &> /dev/null; then
        return 1;
    fi;
    if [ ! "$( git rev-parse --is-inside-git-dir 2> /dev/null )" ]; then
        return 2;
    fi
    branch="$( git symbolic-ref --short -q HEAD 2> /dev/null )"

    if [ "$branch" ]; then
        printf ' \001%s\002(\001%s\002git\001%s\002)\001%s\002-\001%s\002[\001%s\002%s\001%s\002]\001%s\002' "[0;35m" "[39m" "[35m" "[39m" "[35m" "[32m" "${branch}" "[35m" "[39m"
    fi;
}

# grml PS1 string
PS1="\[\e[0m\]\$(_PS1_ret)\[\e[34;1m\]${debian_chroot:+($debian_chroot)}\u\[\e[0m\]@\h \[\e[01m\]\w\$(_PS1_git) \[\e[0m\]% "

you should see something like

user@host ~ % █                                                             v87%

You may not see v87%. That's ok. You can just do Ctrlc and you will see a red error code on the left and a :( at the far right.

So, you will see

130 user@host ~ % █                                                       :( v87%

or

130 user@host ~ % █                                                            :(

Either way, there is something to the right of the cursor.

NOW, if you type some stuff and then Backspace, you will see the :( (and maybe the battery info) disappear! (Pressing up then down does the same thing.)

If you can solve this, you will be my hero! It is probably not very easy, but if there are any clever solutions ... the floor is yours.

  • I'm not sure there is anything you can do. The Readline library seems to be clearing to the end of the line when you backspace at the end of the current input. – chepner Nov 9 '15 at 3:27
  • @chepner do you know of any way to run a command every time a character wizzes off to the terminal? It could be a feature to toggle on and off ... performance vs lookin' gooood. I know (or am quite sure) zsh does something like this because (1) the backspace @ EOL doesn't delete the rest of the line (2) if you type text over the :( (for example) and then backspace off of it, it will reappear! magic – Dylan Nov 9 '15 at 14:14
  • zsh uses its own editor (zle) for handling input, which is both more tightly tied to zsh and more programmable than the library bash uses (Readline). You might want to consider using zsh as your interactive shell instead. – chepner Nov 9 '15 at 14:19
  • @chepner haha. Ok thanks. I am coming from zsh ;) I will take a look at Readline, though ... see what we can do with that. muwahaha – Dylan Nov 9 '15 at 14:26
  • What about literally remapping every key ;) – Dylan Nov 10 '15 at 0:32
0

Not a direct programming answer, but the desired effect might be accomplished by installing liquidprompt, which can show $PS1 battery stats, and many other sorts of useful diagnostic data. To tweak the default settings, just install, run and edit the automatically created ~/.config/liquidpromptrc.

The main program liquidprompt_activate and the scripts it calls are all in shell script, making it an excellent source to study how it does what it does.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.