Limpar linhas de prompt antigas no bash para economizar espaço de rolagem

11

Meu tema do terminal costumava ser assim,

terminal-los antes

Mas achei que o prompt desperdiçou muito espaço. E, mais tarde, tive uma ideia de que poderia limpar o prompt toda vez que executava um comando. Eu estava usando o bash, uma das soluções é usar a preexec_invoke_execfunção.

Eu uso o seguinte comando para limpar os últimos caracteres do prompt:

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

Para que o terminal fique muito limpo, assim,

insira a descrição da imagem aqui

Mas agora o meu problema é que haverá problemas se eu quiser usar vários comandos em uma linha , digamos, quando eu usar for i in ....

Aqui está a versão completa da função no meu .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
fonte
O truque do Glyph Lefkowitz zsh - legal!
2
A solução fácil começa com zsh...
Gilles 'SO- deixa de ser mau'
Eu perdi a sua pergunta lá ...
David Hoelzer
@DavidHoelzer Bem, se você trabalha for i in $(seq 1 10); do ls; donecom a função dele, a saída dos comandos de iteração é "engolida" por assim dizer. Portanto, o OP queria higienizar o comportamento enquanto habilitava esse prompt. A razão pela qual eu apoio isso é o interesse pela conscientização sobre o shell, a usabilidade, o feedback e a portabilidade. O link que eu coloquei no meu comentário anterior leva à postagem sobre superusuário - eles se deram ao trabalho de atribuir esse trecho, por isso é um protótipo que simula a funcionalidade nativa do zsh (que eu acho interessante), na forma de uma função trap aqui.

Respostas:

3

Primeiro preexec_invoke_execdeve ser modificado para impedir várias execuções de preexec. Além disso, modifique preexecpara levar em conta o número real de linhas em $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'

Para preexecpoder ser executado novamente, DONTCLEANPROMPTdeve estar desabilitado ou definido como ''. Isso é feito com PROMPT_COMMAND, que é executado imediatamente antes da emissão do prompt principal. Portanto preexec, será executado uma vez e apenas uma vez para cada linha de comando.

Adaephon
fonte
Sua solução resolve o problema com o forloop! Obrigado! Há mais um inconveniente. O que acontece é que, se você executa lso comando e lsobtém a saída, realiza outra , verá que a última linha da saída anterior é apagada ... você tem uma idéia de como resolver isso?
1
Você provavelmente está usando um prompt com apenas uma única linha. Altere o primeiro eco prexecpara imprimir "\033[1A\033[K\033[31;1m$ \033[0m", que é apenas um \033[1A\033[K(mova 1 linha para cima, exclua até o final da linha) em vez de dois.
Adaephon
Sem falhas! Muito obrigado pela sua solução e dedique um tempo para explicar. Isso resolve o problema do OP e depura a solução ainda mais. Torna utilizável para todos! Felicidades!