Effacer les anciennes lignes d'invite dans bash pour économiser de l'espace de défilement

11

Mon thème de terminal était comme ça,

les terminal avant

Mais je pensais que l'invite gaspillait tellement d'espace. Et plus tard, j'ai eu l'idée que je pouvais nettoyer l'invite à chaque fois que j'exécutais une commande. J'utilisais bash, une des solutions est d'utiliser la preexec_invoke_execfonction.

J'utilise la commande suivante pour nettoyer les derniers caractères d'invite:

echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"

Pour que le terminal soit très propre, comme ça,

entrez la description de l'image ici

Mais maintenant, mon problème est, il y aura un problème si je veux utiliser plusieurs commandes sur une seule ligne , par exemple, lorsque j'utilise for i in ....

Voici la version complète de la fonction dans mon .bashrc,

preexec () { echo -ne "\033[1A\033[K\033[1A\033[K\033[31;1m$ \033[0m"; echo -n "$1"; echo -ne "  \033[37;2m["; echo -n "$2"; echo -ne "]\033[0m\n"; }
preexec_invoke_exec () {
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`; 
    preexec "$this_command" "$this_pwd"
}
trap 'preexec_invoke_exec' DEBUG
Libin Wen
la source
L' astuce Glyph Lefkowitz zsh - sympa!
2
La solution facile commence par zsh
Gilles 'SO- arrête d'être méchant'
J'ai raté votre question là-dedans ...
David Hoelzer
@DavidHoelzer Eh bien, si vous utilisez for i in $(seq 1 10); do ls; donesa fonction, la sortie des commandes d'itération est "avalée" pour ainsi dire. OP a donc voulu désinfecter le comportement tout en activant cette invite. La raison pour laquelle je soutiens cela est l'intérêt pour la sensibilisation à la coque, l'utilisabilité, les commentaires et la portabilité. Le lien que j'avais mis dans mon commentaire précédent mène au post sur superutilisateur - ils ont eu la peine d'attribuer cet extrait, c'est donc un prototype qui émule la fonctionnalité native de zsh (qui je pense est intéressante), sous la forme d'une fonction de trap ici.

Réponses:

3

Doit d'abord preexec_invoke_execêtre modifié pour empêcher plusieurs exécutions de preexec. Modifiez également preexecpour prendre en compte le nombre réel de lignes dans $PS1:

preexec () { 
    # delete old prompt; one "\e[1A\e[K" per line of $PS1
    for (( i=0, l=$(echo -e $PS1 | wc -l) ; i < l ; i++ ))
    do             
        echo -ne "\e[1A\e[K"
    done
    # replacement for prompt
    echo -ne "\e[31;1m$ \e[0m"
    echo -n "$1"
    echo -ne "  \e[37;2m["
    echo -n "$2"
    echo -e "]\e[0m"
}

preexec_invoke_exec () {
    [ -n "$DONTCLEANPROMPT" ] && return
    DONTCLEANPROMPT=x
    [ -n "$COMP_LINE" ] && return  # do nothing if completing
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # don't cause a preexec for $PROMPT_COMMAND
    local this_command=`history 1 | sed -e "s/^[ ]*[0-9]*[ ]*//g"`;
    local this_pwd=`pwd`
    preexec "$this_command" "$this_pwd"
}

trap 'preexec_invoke_exec' DEBUG

PROMPT_COMMAND='unset DONTCLEANPROMPT'

Pour preexecpouvoir être exécuté à nouveau, il DONTCLEANPROMPTdoit être non défini ou défini sur ''. Cela se fait avec PROMPT_COMMAND, qui est exécuté juste avant l'émission de l'invite principale. Par conséquent preexecsera exécuté une fois et une seule fois pour chaque ligne de commande.

Adaephon
la source
Votre solution résout le problème avec la forboucle! Je vous remercie! Il y a un autre inconvénient. Qu'est-ce qui se passe, c'est que si vous faites lssur la commande et que vous avez la sortie, puis vous en faites une autre ls, vous verrez que la dernière ligne de la sortie précédente est effacée ... avez-vous une idée de comment résoudre cela?
1
Vous utilisez probablement une invite avec une seule ligne. Modifiez le premier écho prexecpour imprimer "\033[1A\033[K\033[31;1m$ \033[0m", c'est-à-dire un seul \033[1A\033[K(déplacez 1 ligne vers le haut, supprimez jusqu'à la fin de la ligne) au lieu de deux.
Adaephon
Sans défaut! Merci beaucoup pour votre solution et pour avoir pris le temps de vous expliquer. Cela résout le problème d'OP et débogue encore plus la solution. Le rend utilisable pour tout le monde! À votre santé!