Wie formatiere ich den Pfad in einer zsh-Eingabeaufforderung?

23023
Nicolas Dumazet

Ich hätte gerne einen lesbaren farbigen Pfad. Anstatt einfach% ~ zu verwenden, um zurückzukehren, ~/path/to/foomöchte ich es formatieren ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoo, um die Pfadtrennzeichen hervorzuheben.

Kann ich den Inhalt von PROMPT so definieren, dass der Pfadausdruck auf jeder Anzeige neu ausgewertet wird? So etwas ${${(%):-%~}//\//_some_format_expression/}funktioniert offensichtlich nicht.

Oder sollte ich dies weiter hacken und erzwingen, dass der PROMPT-Wert bei jedem Verzeichniswechsel zurückgesetzt wird?

Jede Lösung, die das Pfadformatierungsziel erreicht, wäre willkommen.

Vielen Dank :)

21
Wenn Sie noch vorhanden sind, möchten Sie möglicherweise die beste Antwort dafür markieren :) Dan Rosenstark vor 14 Jahren 0

4 Antworten auf die Frage

33
Dennis Williamson

zsh

Versuche dies:

setopt PROMPT_SUBST PROMPT='%{$(pwd|grep --color=always /)%${#PWD}G%} %(!.%F.%F)%n%f@%F%m%f%(!.%F.)%#%f ' 

Hier ist eine Aufschlüsselung der Eingabeaufforderung:

  • PROMPT_SUBST aktiviert die Befehlsersetzung in der Eingabeaufforderung (und Parametererweiterung und Arithmetikerweiterung)
  • %{...%} - eine Escape-Sequenz
  • $(pwd|grep --color=always /)- Drucken Sie das aktuelle Verzeichnis und markieren Sie das. /- Die Farbe hängt von der Umgebungsvariablen $ GREP_COLORS (oder ihrem Standardwert) ab. Fettgedruckt ist der Standard
  • %${#PWD}G- Verwenden Sie die Länge in Zeichen des Namens des aktuellen Verzeichnisses als Störschubwert. Die Shell berücksichtigt dabei die Länge der vorangehenden Zeichenfolge (nach dem " %{") anstelle der tatsächlichen Länge der Zeichenfolge, die ANSI-Escape-Sequenzen enthält. Dies verhindert, dass die Shell bezüglich der Position des Cursors relativ zum Ende der Eingabeaufforderung verwechselt wird.
    - - - - - - - Dies ist das Ende des Teils, der Ihre Frage beantwortet. - - - - - - -
  • %(!.%F.%F) - Wenn es sich um eine privilegierte Shell (Root) handelt, setzen Sie die Vordergrundfarbe auf Rot, andernfalls Cyan
  • %n - den Benutzernamen ausgeben
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardeinstellung zurück
  • @ - ein wörtliches Zeichen
  • %F - machen Sie die Vordergrundfarbe gelb
  • %m - den Hostnamen ausgeben
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardeinstellung zurück
  • %(!.%F.) - Wenn dies eine privilegierte Shell (Root) ist, setzen Sie die Vordergrundfarbe auf Rot
  • %#- a #für eine privilegierte Shell oder %für eine nicht privilegierte Shell ausgeben
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardeinstellung zurück

Ich habe den Pfad zuerst in diese Aufforderung zur Betonung gestellt, da die Frage den Pfad betrifft.

alt text

Hier ist eine Version für zsh, die die Farbe des Schrägstrichs ändert, je nachdem, ob Sie root sind (privilegiert), indem Sie die $GREP_COLORSVariable bearbeiten:

setopt PROMPT_SUBST PROMPT='%{$(pwd|([[ $EUID == 0 ]] && GREP_COLORS="mt=01;31" grep --color=always /|| GREP_COLORS="mt=01;34" grep --color=always /))%${#PWD}G%} %(!.%F.%F)%n%f@%F%m%f%(!.%F.)%#%f ' 

Bash

Sie können eine ähnliche Eingabeaufforderung in Bash ausführen. In diesem Beispiel habe ich zuerst den Benutzer und den Hostnamen angegeben, und die Farbe der Schrägstriche ändert sich auch, wenn die UID 0 ist. Warnung: Dadurch wird die $PS1Eingabeaufforderungsvariable von Bash überschrieben . Das sollte kein Problem sein, es sei denn, Sie tun etwas Besonderes oder erwarten, dass sich das Verhalten ändert, wenn Sie diese Variable direkt setzen und dies wirksam ist. Außerdem wird eine Variable namens " usercolor" verwendet, die mit etwas anderem kollidieren kann, obwohl das Ganze in eine Funktion eingefügt werden kann und die Variable als lokal deklariert werden kann.

PROMPT_COMMAND='usercolor="\[\033[0;36m\]";[[ $EUID == 0 ]] && usercolor="\[\033[1;31m\]";PS1="$(pwd)";PS1="$usercolor\u\[\033[0m\]@\[\033[0;33m\]\h\[\033[0m\]:$$usercolor\\$\[\033[0m\] "' 

alt text

Ich habe die Tatsache ausgenutzt, dass Bash nicht über die "Störschub" -Funktion von zsh verfügt, um die Parametererweiterung zu verwenden, um die Schrägstriche bedingt zu färben (anstelle von grep).

nenne mich dumm, aber der einzige falsche Teil, den ich hatte, war die Verwendung von Anführungszeichen anstelle von Anführungszeichen in der PROMPT-Definition. Vielen Dank :) Nicolas Dumazet vor 15 Jahren 0
@NicDumZ, lustig, gestern habe ich anderswo etwa 20 Minuten damit verbracht :) Dan Rosenstark vor 14 Jahren 0
das ist massiv (geeky und) cool. Vielen Dank... Dan Rosenstark vor 14 Jahren 1
Irgendeine Idee, wie man das in Bash macht oder warum es in Bash nicht funktioniert? Für mich mit Bash bleibt es beim ersten Verzeichnis stecken, in dem ich mein Terminal starte, und aktualisiert sich nicht, wenn ich mich bewege. Ich habe gerade das $ (pwd | grep --color = always /) genommen und das in meine PS1 eingefügt und das seltsame Verhalten erhalten. Bearbeiten: OH! Ich habe die Bash-Sektion nicht gesehen. Ibrahim vor 11 Jahren 0
Actually, I'm trying to use your PS1 trick for Bash in my more complex prompt and it's not working, my PWD gets stuck again. But your snippet works as is. What's the purpose of PROMPT_COMMAND? This is what I've got: `PS1="$(pwd)"; PS1="$\[$bldgrn\]\u@$(fgcolor $hostnamecolor)\h$(resetcolor)\[$txtrst\]:\[$bldblu\]$\[\e[00m\]$bldred\$(parse_git_branch)\[$txtrst\] \[$undcyn\]\T \d\[$txtrst\] 95\$ "` colors defined in https://github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh Ibrahim vor 11 Jahren 0
OH! Jetzt sehe ich es. Das Ganze befindet sich in PROMPT_COMMAND, so dass es jedes Mal erneut ausgeführt wird. Funktioniert jetzt gut. Ich verstehe zwar nicht, dass in meiner Eingabeaufforderung eine Funktion parse_git_branch aufgerufen wurde, die Aktualisierungen in Ordnung ist. Ich verstehe daher nicht, warum ich keine Funktion einfügen kann, um die Zeichenfolge für die PWD zu ersetzen. Ibrahim vor 11 Jahren 0
@ Ibrahim: Ich glaube es hat mit * zu tun, wenn * die Funktion aufgerufen wird. `PROMPT_COMMAND` ist früh genug und` PS1` ist zu spät. Dennis Williamson vor 11 Jahren 0
Das war genau das, wonach ich gesucht hatte. Vielen Dank! lohiaguitar91 vor 10 Jahren 0
Warum nicht "$ PWD" verwenden und eine "Gabel" speichern? Tom Hale vor 6 Jahren 0
@TomHale: Ich lade in 'grep', wenn ich also die Variable benutzt, müsste ich sowieso ein 'Echo' formen. Sowohl "pwd" als auch "echo" sind eingebaut. Dennis Williamson vor 6 Jahren 0
4
Nicolas Dumazet

Eine reine zsh-Lösung:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//$/%f}%f ' 
  • ${(%):-%~} ist der aktuelle Pfad.
  • $/%f} ersetzt jedes / in xxxxx durch ein rotes Fett
  • und natürlich muss PROMPT_SUBST eingeschaltet sein.

Ich hatte in meinen Tests doppelte Anführungszeichen verwendet, was keine Substitution zulässt. Bei einfachen Zitaten funktioniert alles gut.

Sie müssen $ PR_BOLD_RED an anderer Stelle definieren. Ich muss PROMPT = '% n @% m verwenden:% {% B% F %} $ {$ {(%): -% ~} // \ //% B% F /% b% f}% b% f '' einschließlich der ** sehr seltsamen ** Flucht der schließenden geschweiften Klammer (nur) nach dem zweiten "Rot". Dennis Williamson vor 15 Jahren 0
Ja, ich benutze die Namensgebung von Aaron Toponce http://pthree.org/wp-content/uploads/2009/03/zsh_prompt, was ich für nützlich hielt. Abgesehen davon muss ich nichts entziehen, es funktioniert wie vorgesehen. Nicolas Dumazet vor 15 Jahren 0
3
Nicolas Dumazet

Nach einigem Hin und Her kann ich eine überschreibende Lösung anbieten chpwd:

doprompt() { local my_path=${(%):-%~} PROMPT="$$/$}$" } doprompt  chpwd() { doprompt # unrelated: set window title [[ -t 1 ]] || return; print -Pn "\e]2;%n@%m: %~\a"; } 
  • Gibt es eine Möglichkeit, diesen Code zu verbessern, um die temporäre my_pathVariable loszuwerden ? Ich kann das / inside% ~ nicht direkt ersetzen ...
  • Jede Lösung, die eine dynamische Syntax verwendet, um das Aufrufen der einzelnen Verzeichnisänderungen zu vermeiden, dopromptist wahrscheinlich sauberer.
0
bcelary

Hier ist mein Versuch (basierend auf NicDumZ's):

setopt PROMPT_SUBST # red, green, yellow, blue, magenta, cyan, white, black # B (bold), K(background color), F(foreground color)  function doprompt { # this is just the directory (%d could be %~ -- I prefer full path always) PROMPT='%F${${(%):-%d}//\//%F%B/%b%F}%f' }  function chpwd() { doprompt } 

Der Unterschied ist, dass ich farbige Pfade verwende, daher muss ich zu meiner ursprünglichen Farbe zurückkehren, sobald der Schrägstrich eingefärbt ist. In meinem Fall ist der Pfad normalerweise gelb und der Schrägstrich wird mit Magenta eingefärbt, danach wird er gelb. Ich bevorzuge die Verwendung von% F% f-Sequenzen, da sie für mich viel lesbarer erscheinen.