come formattare il percorso in un prompt di zsh?


23

Mi piacerebbe avere un percorso colorato leggibile. Ad esempio, invece di usare semplicemente% ~ per tornare, ~/path/to/foovorrei formattarlo ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfooper evidenziare i separatori di percorso.

Posso definire il contenuto di PROMPT in modo che l'espressione del percorso venga rivalutata su ogni display? Qualcosa del genere ${${(%):-%~}//\//_some_format_expression/}ovviamente non funziona.

O dovrei hackerarlo ulteriormente e forzare il valore PROMPT per essere ripristinato ogni volta che cambiamo una directory?

Qualsiasi soluzione che raggiunga l'obiettivo di formattazione del percorso sarebbe benvenuta.

Grazie :)


se esisti ancora potresti voler segnare la migliore risposta per questo :)
Dan Rosenstark,

Risposte:


37

zsh

Prova questo:

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

Ecco una ripartizione del prompt:

  • PROMPT_SUBST attiva la sostituzione dei comandi nel prompt (e l'espansione dei parametri e l'espansione aritmetica)
  • %{...%} - una sequenza di fuga
  • $(pwd|grep --color=always /)- stampa la directory corrente ed evidenzia il /- il colore dipenderà dalla variabile d'ambiente $ GREP_COLORS (o dal suo valore predefinito) - il rosso grassetto è il valore predefinito
  • %${#PWD}G- usa la lunghezza in caratteri del nome della directory corrente come valore glitch. Questo fa sì che la shell consideri questa la lunghezza della sequenza di caratteri precedente (dopo la " %{") anziché la lunghezza effettiva della stringa che include sequenze di escape ANSI. Ciò evita che la shell venga confusa riguardo alla posizione del cursore rispetto alla fine del prompt.
    - - - - - - - questa è la fine della parte che risponde alla tua domanda - - - - - - -
  • %(!.%F{red}.%F{cyan}) - se questa è una shell privilegiata (root) imposta il colore di primo piano su rosso, altrimenti ciano
  • %n - genera il nome utente
  • %f - ripristina il colore di primo piano al valore predefinito
  • @ - un segno letterale
  • %F{yellow} - Rendi il colore di primo piano giallo
  • %m - genera il nome host
  • %f - ripristina il colore di primo piano al valore predefinito
  • %(!.%F{red}.) - se questa è una shell privilegiata (root) imposta il colore di primo piano su rosso
  • %#- output a #per una shell privilegiata o %per una non privilegiata
  • %f - ripristina il colore di primo piano al valore predefinito

Ho messo il percorso al primo posto in questa richiesta di enfasi, poiché la domanda riguarda il percorso.

testo alternativo

Ecco una versione di zsh che cambia il colore della barra a seconda che tu sia root (privilegiato) manipolando la $GREP_COLORSvariabile:

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

Puoi fare un prompt simile in Bash. In questo esempio, ho inserito per primo l'utente e il nome host e il colore delle barre cambia anche quando l'UID è 0. Avvertenza: questo sovrascrive la $PS1variabile prompt di Bash . Questo non dovrebbe essere un problema a meno che tu non stia facendo qualcosa di speciale o non ti aspetti che il comportamento cambi quando imposti direttamente quella variabile e questo è in vigore. Inoltre, utilizza una variabile chiamata " usercolor" che può scontrarsi con qualcos'altro, sebbene l'intera cosa possa essere inserita in una funzione e la variabile dichiarata 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\] "'

testo alternativo

Ho approfittato del fatto che Bash non ha la funzione "glitch" di zsh per usare la sostituzione dell'espansione dei parametri per colorare condizionatamente le barre (invece di usare grep).


chiamami stupido, ma l'unica parte sbagliata che ho avuto è stato l'uso di virgolette doppie invece di virgolette singole nella definizione PROMPT. Grazie :)
Nicolas Dumazet,

@NicDumZ, divertente, ho passato circa 20 minuti su quel problema altrove ieri :)
Dan Rosenstark,

1
questo è enormemente (geniale e) figo. Grazie ...
Dan Rosenstark,

Hai idea di come farlo in Bash o perché non funziona in Bash? Per me con Bash si blocca nella prima directory in cui avvio il mio terminale e non si aggiorna quando mi muovo. Ho appena preso $ (pwd | grep --color = always /) e l'ho messo nella mia PS1 e ho ottenuto lo strano comportamento. Modifica: OH! Non ho visto la sezione Bash lol.
Ibrahim,

In realtà, sto cercando di usare il tuo trucco PS1 per Bash nel mio prompt più complesso e non funziona, il mio PWD si blocca di nuovo. Ma il tuo frammento funziona così com'è. Qual è lo scopo di PROMPT_COMMAND? Questo è quello che ho: 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\$ "colori definiti in github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim

4

Dopo alcuni passaggi, posso fornire una soluzione prioritaria 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";
}
  • C'è un modo per migliorare questo codice per sbarazzarsi del my_pathvar temporaneo ? Non riesco a sostituire direttamente / inside% ~ ...
  • Qualsiasi soluzione che utilizza una sintassi dinamica per evitare di chiamare ogni cambio di directory dopromptè probabilmente più pulita.

4

Una soluzione zsh pura:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} è il percorso corrente.
  • ${xxxxx//\//${PR_BOLD_RED}/%f} sostituisce ogni / in xxxxx con uno in grassetto di colore rosso
  • e ovviamente PROMPT_SUBST deve essere attivo.

Nei miei test avevo usato virgolette doppie, che non consentono la sostituzione. Tutto funziona bene con virgolette singole.


Devi aver $PR_BOLD_REDdefinito altrove. Devo usare PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'includendo la strana evasione del parentesi graffa di chiusura (solo) dopo il secondo "rosso".
In pausa fino a nuovo avviso.

sì, uso i nomi di Aaron Toponce pthree.org/wp-content/uploads/2009/03/zsh_prompt che ho trovato utile. Oltre a ciò, non devo sfuggire a nulla, funziona come previsto.
Nicolas Dumazet,

0

Ecco il mio tentativo (basato su 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 differenza è che sto usando il percorso colorato, quindi devo tornare al mio colore originale per il percorso una volta che la barra viene colorata. Nel mio caso il percorso è normalmente giallo e la barra si colora di magenta, quindi ritorna al giallo. Preferisco anche usare le sequenze% F% f poiché sembrano molto più leggibili per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.