comment formater le chemin dans une invite zsh?

22

J'aimerais avoir un chemin coloré lisible. Par exemple, au lieu d’utiliser% ~ pour retourner, ~/path/to/fooje voudrais le formater ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoopour mettre en évidence les séparateurs de chemin.

Puis-je définir le contenu de PROMPT afin que l'expression de chemin soit réévaluée sur chaque affichage? Quelque chose comme ${${(%):-%~}//\//_some_format_expression/}évidemment ne fonctionne pas.

Ou devrais-je pirater cela plus loin et forcer la valeur PROMPT à se réinitialiser chaque fois que nous changeons de répertoire?

Toute solution permettant d'atteindre l'objectif de formatage du chemin serait la bienvenue.

Merci :)

Nicolas Dumazet
la source
si vous existez encore, vous voudrez peut-être indiquer la meilleure réponse pour cela :)
Dan Rosenstark

Réponses:

34

zsh

Essaye ça:

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

Voici une ventilation de l'invite:

  • PROMPT_SUBST active la substitution de commande dans l'invite (et le développement de paramètres et le développement arithmétique)
  • %{...%} - une séquence d'échappement
  • $(pwd|grep --color=always /)- affiche le répertoire en cours et met en surbrillance /- la couleur dépend de la variable d'environnement $ GREP_COLORS (ou de sa valeur par défaut) - le rouge gras est la valeur par défaut
  • %${#PWD}G- utilisez la longueur en caractères du nom du répertoire en cours comme valeur de pépin. Cela oblige le shell à considérer la longueur de la séquence de caractères précédente (après le " %{") à la place de la longueur réelle de la chaîne qui inclut les séquences d'échappement ANSI. Cela empêche le shell d’être dérouté par la position du curseur par rapport à la fin de l’invite.
    - - - - - - - c'est la fin de la partie qui répond à votre question - - - - - - -
  • %(!.%F{red}.%F{cyan}) - s'il s'agit d'un shell privilégié (racine), définissez la couleur de premier plan sur rouge, sinon cyan
  • %n - sortir le nom d'utilisateur
  • %f - réinitialiser la couleur de premier plan à la valeur par défaut
  • @ - un signe littéral
  • %F{yellow} - faire la couleur de premier plan jaune
  • %m - affiche le nom d'hôte
  • %f - réinitialiser la couleur de premier plan à la valeur par défaut
  • %(!.%F{red}.) - s'il s'agit d'un shell privilégié (racine), définissez la couleur de premier plan sur rouge
  • %#- sortie a #pour un shell privilégié ou %pour un non privilégié
  • %f - réinitialiser la couleur de premier plan à la valeur par défaut

J'ai mis le chemin d'abord dans cette invite, car la question concerne le chemin.

texte alternatif

Voici une version pour zsh qui modifie la couleur de la barre oblique selon que vous êtes root (privilégié) en manipulant la $GREP_COLORSvariable:

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 '

Frapper

Vous pouvez faire une invite similaire dans Bash. Dans cet exemple, j'ai placé l'utilisateur et le nom d'hôte en premier et la couleur des barres obliques change également lorsque l'UID est égal à 0. Avertissement: ceci écrase la $PS1variable d'invite de Bash . Cela ne devrait pas poser de problème, sauf si vous faites quelque chose de spécial ou si vous vous attendez à ce que le comportement change lorsque vous définissez cette variable directement et que ceci est appliqué. En outre, cela utilise une variable appelée " usercolor" qui peut entrer en collision avec autre chose, bien que tout cela puisse être mis dans une fonction et que la variable soit déclarée locale.

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\] "'

texte alternatif

J'ai profité du fait que Bash ne dispose pas de la fonction "glitch" de zsh pour utiliser la substitution d'expansion de paramètre pour colorier les barres obliques de manière conditionnelle (au lieu d'utiliser grep).

Dennis Williamson
la source
appelez-moi stupide, mais la seule partie fausse que j'avais était l'utilisation de guillemets doubles au lieu de guillemets simples dans la définition de PROMPT. Merci :)
Nicolas Dumazet
@NicDumZ, drôle, j'ai passé environ 20 minutes sur ce problème ailleurs hier :)
Dan Rosenstark
1
c'est massivement (geek et) cool. Merci ...
Dan Rosenstark
Avez-vous une idée de comment faire cela dans Bash ou pourquoi cela ne fonctionne pas dans Bash? Pour moi avec Bash, il reste bloqué au premier répertoire où je démarre mon terminal et ne se met pas à jour lorsque je me déplace. Je viens de prendre le $ (pwd | grep --color = always /) et le mettre dans ma PS1 et j'ai le comportement étrange. Edit: OH! Je n'ai pas vu la section Bash lol.
Ibrahim
En fait, j'essaie d'utiliser votre astuce PS1 pour Bash dans mon invite plus complexe et cela ne fonctionne pas, ma PWD se bloque à nouveau. Mais votre extrait fonctionne tel quel. Quel est le but de PROMPT_COMMAND? Voici ce que j'ai: les 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\$ "couleurs définies dans github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim
4

Après quelques échanges, je peux fournir une solution prioritaire 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";
}
  • Existe-t-il un moyen d'améliorer ce code pour se débarrasser de la my_pathvariable temporaire ? Je ne peux pas remplacer directement le / inside% ~ ...
  • Toute solution utilisant une syntaxe dynamique pour éviter d'appeler à chaque changement de répertoire dopromptest probablement plus propre.
Nicolas Dumazet
la source
4

Une solution pure zsh:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} est le chemin actuel.
  • ${xxxxx//\//${PR_BOLD_RED}/%f} remplace chaque / dans xxxxx par une couleur rouge vif
  • et bien sur, PROMPT_SUBST doit être activé.

J'avais utilisé des guillemets doubles dans mes tests, ce qui ne permet pas la substitution. Tout fonctionne bien avec des guillemets simples.

Nicolas Dumazet
la source
Vous devez avoir $PR_BOLD_REDdéfini ailleurs. Je dois utiliser PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'notamment l' échappement très étrange de l'accolade fermante (uniquement) après le deuxième "rouge".
Dennis Williamson
oui, j'utilise les noms d'Aaron Toponce pthree.org/wp-content/uploads/2009/03/zsh_prompt, ce que j'ai trouvé utile. En plus de cela, je n'ai rien à échapper, cela fonctionne comme prévu.
Nicolas Dumazet
0

Voici ma tentative (basée sur NicDumZ):

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
}

La différence est que j'utilise un chemin coloré. Je dois donc revenir à la couleur d'origine du chemin une fois que la barre oblique est colorée. Dans mon cas, le chemin est normalement jaune et la barre oblique se colore avec du magenta, puis elle redevient jaune. Je préfère également utiliser les séquences% F% f car elles me semblent beaucoup plus lisibles.

bcelaire
la source