Bash $ PROMPT_COMMAND bringt die Anzeige des Bildlaufverlaufs durcheinander

7

Ich habe ein eingerichtet PROMPT_COMMAND, um den aktuellen Zweig anzuzeigen, während ich in einem Git-Repo bin.

Der relevante Teil meiner .bashrc ist:

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

wo ~ / bin / myprompt ist:

#!/usr/bin/env ruby
green = "\033[32m"
bold = "\033[1m"
underline = "\033[4m"
reset = "\033[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

Es funktioniert größtenteils einwandfrei. Das einzige Problem ist, dass der Befehl manchmal über meine Eingabeaufforderung geschrieben wird, wenn ich mit den Pfeiltasten durch den Befehlsverlauf scrolle. Angenommen, die folgende Sitzung:

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

Dann drücke ich den Aufwärtspfeil, um durch den Befehlsverlauf zu scrollen. Jede Zeile zeigt das Ergebnis eines Pfeildrucks:

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

Wie Sie sehen, wurde der Befehl beim letzten Drücken des Pfeils über meine Eingabeaufforderung geschrieben.

Hat jemand dies erlebt und / oder weiß, wie man es behebt?

adrusi
quelle

Antworten:

11

Anstatt es einzulegen PROMPT_COMMAND, setzen Sie es ein PS1:

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

Wenn es PS1aktiviert ist, zählt bash die Anzahl der Zeichen, die gedruckt werden, damit es beim Scrollen durch Ihren Verlauf korrekt neu gezeichnet werden kann. Deshalb bash die hat \[und \]Sonderzeichen-sie bash sagen , dass die eingeschlossenen Zeichen nicht druckbar sind, die aus bash Figur hilft , wie Sie die Eingabeaufforderung , wenn nötig neu zu zeichnen.

Beachten Sie, dass sich die Befehlsersetzung in einfachen Anführungszeichen befindet. Dies verhindert eine Erweiterung zur Zuweisungszeit. Wenn die Befehlssubstitution in doppelten oder nicht in Anführungszeichen gesetzt wurde, wird die Ausgabe von zum mypromptZeitpunkt der Zuweisung einmal erfasst und bleibt statisch. Um Variablenwerte zu unterstützen, die sich im Laufe der Zeit ändern, erweitert die Shell den Wert PS1jedes Mal, wenn die Eingabeaufforderung angezeigt wird. Dies bedeutet, dass eine Erweiterung zum Zeitpunkt der Zuweisung durch Anführungszeichen verhindert werden sollte. Dies bedeutet auch, dass Sie auf die Geschwindigkeit achten müssen: Wenn die Befehlsersetzung 1 Sekunde dauert, dauert die Anzeige Ihrer Eingabeaufforderung 1 Sekunde.

Richard Hansen
quelle
Danke, aber würde das nicht statisch die Ausgabe von mypromptPS1 zuweisen ? Ich erinnere mich, dass ich zuvor versucht habe, so etwas zu tun.
1
Ups, das ist ein Fehler. Ich habe es repariert. Die Befehlsersetzung sollte in einfachen Anführungszeichen stehen. Ich habe die Angewohnheit, Variablen und Befehlsersetzungen zur Zuweisungszeit zu erweitern, weil ich das 99% der Zeit möchte. PS1ist eine der seltenen Ausnahmen.
Richard Hansen
Danke für die ausführliche Erklärung; Das hat mir geholfen, meine PS1 zu reparieren. Ich hatte, PS1='\033]0;\u@\h\007[\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\]]\$ 'was den Fenstertitel festlegt und 'user @ host full-path $' anzeigt, aber der Cursor wurde unerwartet umbrochen. Nach dem Hinzufügen \[und \]so aussehen: PS1='\[\033]0;\u@\h\007\][\[\033[01;32m\]\u@\h\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\]]\$ 'es funktioniert gut!
Benjamin Goodacre
0

PROMPT_COMMAND kann einen Befehl enthalten, der ausgeführt wird, bevor die neue Eingabeaufforderung von bash gedruckt wird (also bevor PS1 ausgewertet wird).

Mit Git 1.8.1 wurde Code veröffentlicht, um dies effektiv mit PROMPT_COMMAND zu tun. Siehe die Verwendung von git-prompt.sh mit PROMPT_COMMAND . Der Code kann mit früheren Versionen von git verwendet werden. Kopieren Sie einfach die Datei Contrib / Completion / git-prompt.sh an einen Ort, an dem Sie sie aus Ihrer .bashrc-Datei beziehen können.

Prost

Simon

Simon
quelle