Bash $ PROMPT_COMMAND exibindo o histórico de rolagem

7

Eu configurei um PROMPT_COMMAND para exibir o ramo atual enquanto estou em um repositório do git.

A parte relevante do meu .bashrc é:

export PS1=" \[3[34m\]\$\[3[0m\] "
export PROMPT_COMMAND="$HOME/bin/myprompt"

onde ~ / bin / myprompt é:

#!/usr/bin/env ruby
green = "3[32m"
bold = "3[1m"
underline = "3[4m"
reset = "3[0m"

home_regex = Regexp.new "^#{ENV["HOME"]}"
Dir.chdir ENV["PWD"]

out = 
  underline + bold + green +
  'pwd'.gsub(home_regex, "~").chomp +
  reset

if 'git log 2>&1 | grep ^fatal'.chomp == ""
  out += "#{underline}#{green} (#{'git branch | grep ^\* | sed s/^..//g'.chomp})#{reset}"
end

print out

Funciona bem na maior parte do tempo, o único problema é que quando uso as teclas de seta para rolar pelo histórico de comandos, às vezes o comando é gravado no meu prompt. Suponha a seguinte sessão:

~ $ pwd
/Users/Adrian
~ $ cd sibilant
~/sibilant (master) $ pwd
/Users/Adrian/sibilant
~/sibilant (master) $

Depois, pressiono a seta para cima para percorrer o histórico de comandos. cada linha mostra o resultado de um pressionamento da seta:

~/sibilant (master) $ pwd
~/sibilant (master) $ cd sibilant
~/spwd

como você pode ver, a última vez que pressionei a seta, o comando foi escrito no meu prompt.

Alguém já experimentou isso e / ou sabe como consertar isso?

    
por adrusi 13.02.2012 / 02:29

2 respostas

11

Em vez de colocá-lo em PROMPT_COMMAND , coloque-o em PS1 :

PS1='$($HOME/bin/myprompt) \[3[34m\]\$\[3[0m\] '

Quando está em PS1 , bash conta o número de caracteres que são impressos para que ele possa redesenhar corretamente quando você percorre seu histórico. É por isso que o bash tem os caracteres especiais \[ e \] - eles dizem que os caracteres incluídos não são imprimíveis, o que ajuda a descobrir como redesenhar o prompt quando necessário.

Observe que a substituição de comandos está dentro das aspas simples. Isso evita a expansão no momento da atribuição. Se a substituição do comando estivesse entre aspas duplas ou sem aspas, a saída de myprompt seria capturada uma vez no tempo de atribuição e permaneceria estática. Para suportar valores de variáveis que mudam com o tempo, o shell expande o valor de PS1 sempre que o prompt é exibido. Isso significa que a expansão deve ser evitada no tempo de atribuição, citando. Isso também significa que você precisa ter cuidado com a velocidade: se a substituição do comando levar 1 segundo para ser concluída, seu prompt demorará 1 segundo para ser exibido.

    
por 13.02.2012 / 02:39
0

PROMPT_COMMAND pode conter um comando que é executado antes que o novo prompt seja impresso por bash (portanto, antes do PS1 ser avaliado).

Com o git 1.8.1, o código para fazer isso efetivamente com o PROMPT_COMMAND foi lançado. Veja usando git-prompt.sh com PROMPT_COMMAND . O código pode funcionar com versões anteriores do git, basta copiar o arquivo contrib / completion / git-prompt.sh para um lugar onde você possa obtê-lo do seu .bashrc.

Felicidades

Simon

    
por 18.01.2013 / 21:42

Tags