![Wie korrigiere ich die Umbruchfunktion meiner Farb-Bash-Eingabeaufforderung?](https://rvso.com/image/1259391/Wie%20korrigiere%20ich%20die%20Umbruchfunktion%20meiner%20Farb-Bash-Eingabeaufforderung%3F.png)
Ich habe eine Bash-Eingabeaufforderung (mit PROMPT_FUNCTION) wie folgt definiert:
function get_hg_prompt_prefix() {
local APPLIED_COLOR=$1; shift
local UNAPPLIED_COLOR=$1; shift
local ALERT_COLOUR=$1; shift
local TEXTCOLOR=$1; shift
local mercurial_prompt_line="{{patches|join(:)|pre_applied(${APPLIED_COLOR})|post_applied(${TEXTCOLOR})|pre_unapplied(${UNAPPLIED_COLOR})|post_unapplied(${TEXTCOLOR})}\n\r}"
local mercurial_status_prompt="{ ${ALERT_COLOUR}{status}${TEXTCOLOR}}"
echo "$(hg prompt "${mercurial_prompt_line}" 2>/dev/null)$(hg prompt "${mercurial_status_prompt}" 2>/dev/null)"
}
function set_prompt() {
bright='\[[01m\]'
colors_reset='\[[00m\]'
HOSTCOLOR=${colors_reset}='\[[34m\]'
USERCOLOR=${colors_reset}='\[[01m\]'
TEXTCOLOR=${colors_reset}='\[[32m\]'
APPLIED_COLOR=${colors_reset}='\[[32m\]'
UNAPPLIED_COLOR=${colors_reset}='\[[37m\]'
ALERT_COLOUR=${colors_reset}='\[[31m\]'
hg_status="$(get_hg_prompt_prefix $APPLIED_COLOR $UNAPPLIED_COLOR $ALERT_COLOUR $TEXTCOLOR)"
ps1_prefix="${hg_status}$colors_reset($bright$(basename $VIRTUAL_ENV)$colors_reset) "
PROMPTEND='$'
PS1="${ps1_prefix}${USERCOLOR}\u${colors_reset}${TEXTCOLOR}@${colors_reset}${HOSTCOLOR}\h${colors_reset}${TEXTCOLOR} (\W) ${PROMPTEND}${colors_reset} "
}
PROMPT_COMMAND=set_prompt
Im Allgemeinen erhalte ich dadurch eine mehrzeilige Eingabeaufforderung, in der einige HG-Statusinformationen sowie meine aktuelle virtuelle Umgebung angezeigt werden. Diese sieht (ohne Farbe) folgendermaßen aus:
buggy-wins.patch
! (saas) user@computer (~) $
Das Problem ist, dass dies die Berechnung der Länge der Eingabeaufforderung durcheinander bringt (glaube ich!) und seltsame Probleme mit der Terminalumbruchfunktion und der Cursorplatzierung verursacht. In einem 80-Zeichen-Terminal sehe ich beispielsweise die folgende Eingabeaufforderung (das von ** umgebene Zeichen ist die Cursorposition):
~) $ **a**nis) crose@chris-rose (~
In Terminals, die breit genug sind, um die Eingabeaufforderung anzuzeigen, erfolgt der Zeilenumbruch viel früher als er sollte. Hier ist der größte Text, den ich auf dieErsteZeile der Eingabeaufforderung in einem 108 Zeichen breiten Terminalfenster (auch hier markiert ** meine Cursorposition):
**(**advanis) crose@chris-rose (~) $ sdkfjlskdjflksdjff
Wenn die Zeile umgebrochen wird, überschreibt sie die Eingabeaufforderung. Die zweite Eingabezeile reicht jedoch bis zum Rand des Terminals und wird dann korrekt umgebrochen.
Offensichtlich stimmt also etwas mit der Breite der Eingabeaufforderung nicht überein. Wie kann ich Bash dazu bringen, die Länge der PS1-Zeichenfolge nicht anhand der ANSI-Escape-Codes, sondern anhand der tatsächlich angezeigten Länge der Eingabeaufforderung zu bestimmen?
Antwort1
bash
verwendet \[
\]
, um die „angezeigte Länge“ zu bestimmen: Text zwischen diesen beiden Escape-Zeichen wird als nicht druckbar betrachtet und nicht in die Gesamtlänge eingerechnet; alles andere schon.
Es scheint ein Problem mit Ihren Variablen zu geben: bright='\[[01m\]'
enthält eigentlich kein ESC-Zeichen, [01m
wird also als normaler Text gedruckt, aber nicht in die Länge einberechnet. Es sollte sein '\[\e[01m\]'
. Dasselbe gilt für alle anderen Variablen.
Verwandt:
- In Bash können Sie direkt
\$(hg_status)
in einfügen$PS1
, ohne dass ein separates erforderlich istPROMPT_COMMAND
.