Wie formatiere ich den Pfad in einer zsh-Eingabeaufforderung?

23

Ich hätte gerne einen lesbaren farbigen Pfad. Anstatt zum Zurückgeben einfach% ~ zu verwenden, ~/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 bei jeder Anzeige neu ausgewertet wird? Sowas ${${(%):-%~}//\//_some_format_expression/}funktioniert offensichtlich nicht.

Oder sollte ich das weiter hacken und den PROMPT-Wert zwingen, jedes Mal zurückgesetzt zu werden, wenn wir ein Verzeichnis wechseln?

Jede Lösung, die das Ziel der Pfadformatierung erreicht, ist willkommen.

Vielen Dank :)

Nicolas Dumazet
quelle
wenn es dich noch gibt, solltest du vielleicht die beste Antwort dafür markieren :)
Dan Rosenstark

Antworten:

36

zsh

Versuche dies:

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

Hier ist eine Aufschlüsselung der Eingabeaufforderung:

  • PROMPT_SUBST aktiviert die Befehlsersetzung in der Eingabeaufforderung (und Parametererweiterung und arithmetische Erweiterung)
  • %{...%} - eine Fluchtsequenz
  • $(pwd|grep --color=always /)- Das aktuelle Verzeichnis drucken und markieren. /- Die Farbe hängt von der Umgebungsvariablen $ GREP_COLORS (oder ihrem Standardwert) ab. - Die Standardeinstellung ist Fettrot
  • %${#PWD}G- Verwenden Sie die Länge des Namens des aktuellen Verzeichnisses in Zeichen als Störimpuls. Dies veranlasst die Shell, dies als die Länge der vorhergehenden Zeichenfolge (nach dem " %{") anstelle der tatsächlichen Länge der Zeichenfolge zu betrachten, die ANSI-Escape-Folgen enthält. Dies verhindert, dass die Shell über die Position des Cursors relativ zum Ende der Eingabeaufforderung verwirrt wird.
    - - - - - - - das ist das Ende des Teils, der Ihre Frage beantwortet - - - - - -
  • %(!.%F{red}.%F{cyan}) - Wenn es sich um eine privilegierte Shell (Root) handelt, setzen Sie die Vordergrundfarbe auf Rot, andernfalls auf Cyan
  • %n - Benutzernamen ausgeben
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardfarbe zurück
  • @ - ein wörtliches Zeichen
  • %F{yellow} - mach die Vordergrundfarbe gelb
  • %m - den Hostnamen ausgeben
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardfarbe zurück
  • %(!.%F{red}.) - Wenn dies eine privilegierte Shell (root) ist, setzen Sie die Vordergrundfarbe auf rot
  • %#- Geben Sie a #für eine privilegierte Shell oder %für eine nicht privilegierte Shell aus
  • %f - Setzen Sie die Vordergrundfarbe auf die Standardfarbe zurück

Ich habe den Pfad an erster Stelle in dieser Eingabeaufforderung zur Betonung gesetzt, 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 (privilegiert) sind, 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{red}.%F{cyan})%n%f@%F{yellow}%m%f%(!.%F{red}.)%#%f '

Bash

Sie können eine ähnliche Eingabeaufforderung in Bash ausführen. In diesem Beispiel habe ich den Benutzer- und Hostnamen an die erste Stelle gesetzt und die Farbe der Schrägstriche ändert sich auch, wenn die UID 0 ist. Warnung: Dadurch wird die $PS1Eingabeaufforderungsvariable von Bash überschrieben . Dies sollte kein Problem sein, es sei denn, Sie tun etwas Besonderes oder Sie erwarten, dass sich das Verhalten ändert, wenn Sie diese Variable direkt festlegen und dies in Kraft tritt. Dies verwendet auch eine Variable mit dem Namen "usercolor " verwendet, die mit etwas anderem kollidieren kann, obwohl das Ganze in eine Funktion gestellt und die Variable als local deklariert werden könnte.

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\]:${PS1//\//$usercolor/\[\033[0m\]}$usercolor\\$\[\033[0m\] "'

Alt-Text

Ich habe die Tatsache ausgenutzt, dass Bash nicht über zshs "Glitch" -Funktion verfügt, um die Parametererweiterungsersetzung zu verwenden, um die Schrägstriche bedingt einzufärben (anstatt grep zu verwenden).

Bis auf weiteres angehalten.
quelle
Nennen Sie mich dumm, aber der einzige falsche Teil, den ich hatte, war die Verwendung von doppelten Anführungszeichen anstelle von einfachen Anführungszeichen in der PROMPT-Definition. Danke :)
Nicolas Dumazet
@NicDumZ, lustig, ich habe gestern an anderer Stelle ungefähr 20 Minuten mit diesem Problem verbracht :)
Dan Rosenstark
1
das ist massiv (geeky und) cool. Danke ...
Dan Rosenstark
Irgendeine Idee, wie man das in Bash macht, oder warum es in Bash nicht funktioniert? Bei Bash bleibt es nur beim ersten Verzeichnis hängen, in dem ich mein Terminal starte, und es wird nicht aktualisiert, wenn ich mich bewege. Ich habe einfach das $ genommen (pwd | grep --color = always /) und das in meine PS1 gesteckt und das seltsame Verhalten festgestellt. Bearbeiten: OH! Ich habe den Bash-Abschnitt nicht gesehen, lol.
Ibrahim
Eigentlich versuche ich, deinen PS1-Trick für Bash in meiner komplexeren Eingabeaufforderung zu verwenden, und es funktioniert nicht, mein PWD bleibt wieder hängen. Aber dein Snippet funktioniert so wie es ist. Was ist der Zweck von PROMPT_COMMAND? Dies ist, was ich habe: PS1="$(pwd)"; PS1="${debian_chroot:+($debian_chroot)}\[$bldgrn\]\u@$(fgcolor $hostnamecolor)\h$(resetcolor)\[$txtrst\]:\[$bldblu\]${PS1//\//$txtred/$bldblu}\[\e[00m\]$bldred\$(parse_git_branch)\[$txtrst\] \[$undcyn\]\T \d\[$txtrst\] 95\$ "Farben definiert in github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim
4

Nach einigem Hin und Her kann ich eine übergeordnete Lösung bereitstellen chpwd:

doprompt() {
  local my_path=${(%):-%~}
  PROMPT="${yourstuff}${my_path//\//${PR_BOLD_RED}/${reset_color}}${otherstuff}"
}
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 jedes Verzeichniswechsels zu vermeiden, dopromptist wahrscheinlich sauberer.
Nicolas Dumazet
quelle
4

Eine reine zsh-Lösung:

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

Ich habe in meinen Tests doppelte Anführungszeichen verwendet, die keine Substitution zulassen. Alles funktioniert gut mit einfachen Anführungszeichen.

Nicolas Dumazet
quelle
Sie müssen an $PR_BOLD_REDanderer Stelle definiert haben . Ich muss PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'auch das sehr seltsame Entkommen der schließenden geschweiften Klammer (nur) nach dem zweiten "roten" verwenden.
Bis auf weiteres angehalten.
ja, ich benutze Aaron Toponces Namen pthree.org/wp-content/uploads/2009/03/zsh_prompt, was ich nützlich fand. Ansonsten muss ich mir nichts entgehen lassen, es funktioniert wie vorgesehen.
Nicolas Dumazet
0

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{yellow}${${(%):-%d}//\//%F{magenta\}%B/%b%F{yellow\}}%f'
}

function chpwd() {
    doprompt
}

Der Unterschied besteht darin, dass ich einen farbigen Pfad verwende. Daher muss ich zu meiner ursprünglichen Farbe für den Pfad zurückkehren, sobald der Schrägstrich farbig wird. In meinem Fall ist der Pfad normalerweise gelb, und der Schrägstrich wird mit Magenta gefärbt, und dann wird er wieder gelb. Ich bevorzuge auch die Verwendung von% F% f Sequenzen, da diese für mich viel besser lesbar erscheinen.

bcelary
quelle