¿Cómo formatear la ruta en un indicador de zsh?

22

Me encantaría tener un camino de color legible. Por ejemplo, en lugar de simplemente usar% ~ para volver, ~/path/to/foome gustaría formatearlo ~$RED/$NOCOLORpath$RED/$NOCOLORto$RED/$NOCOLORfoopara resaltar los separadores de ruta.

¿Puedo definir el contenido de PROMPT para que la expresión de ruta se vuelva a evaluar en cada pantalla? Algo así ${${(%):-%~}//\//_some_format_expression/}obviamente no funciona.

¿O debería piratear esto más y forzar el valor PROMPT para que se restablezca cada vez que cambiemos un directorio?

Cualquier solución que logre el objetivo de formato de ruta será bienvenida.

Gracias :)

Nicolas Dumazet
fuente
si aún existe, puede marcar una mejor respuesta para esto :)
Dan Rosenstark

Respuestas:

34

zsh

Prueba esto:

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

Aquí hay un desglose de la solicitud:

  • PROMPT_SUBST activa la sustitución de comandos en la solicitud (y la expansión de parámetros y la expansión aritmética)
  • %{...%} - una secuencia de escape
  • $(pwd|grep --color=always /)- imprima el directorio actual y resalte el /- el color dependerá de la variable de entorno $ GREP_COLORS (o su valor predeterminado) - el rojo en negrita es el predeterminado
  • %${#PWD}G- use la longitud en caracteres del nombre del directorio actual como un valor de falla. Esto hace que el shell considere esto como la longitud de la secuencia de caracteres anterior (después de " %{") en lugar de la longitud real de la cadena que incluye secuencias de escape ANSI. Esto evita que el shell se confunda sobre la posición del cursor con respecto al final de la solicitud.
    - - - - - - - este es el final de la parte que responde a su pregunta - - - - - - -
  • %(!.%F{red}.%F{cyan}) - si se trata de un shell privilegiado (raíz), configure el color de primer plano en rojo, de lo contrario, cian
  • %n - generar el nombre de usuario
  • %f - restablecer el color de primer plano al predeterminado
  • @ - un literal en el signo
  • %F{yellow} - hacer que el primer plano sea de color amarillo
  • %m - salida del nombre de host
  • %f - restablecer el color de primer plano al predeterminado
  • %(!.%F{red}.) - si se trata de un shell privilegiado (raíz), configure el color de primer plano en rojo
  • %#- salida a #para un shell privilegiado o %para uno no privilegiado
  • %f - restablecer el color de primer plano al predeterminado

Puse el camino primero en este mensaje para enfatizar, ya que la pregunta se refiere al camino.

texto alternativo

Aquí hay una versión para zsh que cambia el color de la barra diagonal dependiendo de si es root (privilegiado) al manipular 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 '

Golpetazo

Puede hacer un aviso similar en Bash. En este ejemplo, puse el nombre de usuario y host primero y el color de las barras también cambia cuando el UID es 0. Advertencia: esto sobrescribe la $PS1variable de solicitud de Bash . Eso no debería ser un problema a menos que esté haciendo algo especial o espere que el comportamiento cambie cuando configura esa variable directamente y esto está vigente. Además, esto usa una variable llamada " usercolor" que puede colisionar con otra cosa, aunque todo esto podría ponerse en una función y la variable declarada local.

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

texto alternativo

Aproveché el hecho de que Bash no tiene la función "falla" de zsh para usar la sustitución de expansión de parámetros para colorear condicionalmente las barras (en lugar de usar grep).

Dennis Williamson
fuente
llámame estúpido, pero la única parte incorrecta que tuve fue el uso de comillas dobles en lugar de comillas simples en la definición PROMPT. Gracias :)
Nicolas Dumazet
@NicDumZ, curioso, ayer pasé unos 20 minutos en ese problema en otro lugar :)
Dan Rosenstark
1
Esto es masivamente (geek y) genial. Gracias ...
Dan Rosenstark
¿Alguna idea de cómo hacer esto en Bash o por qué no funciona en Bash? Para mí con Bash, simplemente se atasca en el primer directorio en el que inicio mi terminal, y no se actualiza cuando me muevo. Acabo de tomar $ (pwd | grep --color = always /) y lo puse en mi PS1 y obtuve el comportamiento extraño. Editar: OH! No vi la sección Bash jajaja.
Ibrahim
En realidad, estoy tratando de usar tu truco de PS1 para Bash en mi mensaje más complejo y no funciona, mi PWD se atasca nuevamente. Pero tu fragmento funciona como está. ¿Cuál es el propósito de PROMPT_COMMAND? Esto es lo que tengo: 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\$ "colores definidos en github.com/ibrahima/dotfiles/blob/master/.bashrc.d/prompt.sh
Ibrahim
4

Después de dar una vuelta, puedo proporcionar una solución que anule 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";
}
  • ¿Hay alguna manera de mejorar este código para deshacerse de la my_pathvar temporal ? No puedo reemplazar directamente el / inside% ~ ...
  • Cualquier solución que use una sintaxis dinámica para evitar llamar a cada cambio de directorio dopromptes probablemente más limpia.
Nicolas Dumazet
fuente
4

Una solución zsh pura:

PROMPT='%n@%m: %{$PR_BOLD_RED%}${${(%):-%~}//\//${PR_BOLD_RED}/%f}%f '
  • ${(%):-%~} es el camino actual
  • ${xxxxx//\//${PR_BOLD_RED}/%f} reemplaza cada / en xxxxx por una negrita de color rojo
  • y, por supuesto, PROMPT_SUBST tiene que estar activado.

Estaba usando comillas dobles en mis pruebas, lo que no permite la sustitución. Todo funciona bien con comillas simples.

Nicolas Dumazet
fuente
Debes haber $PR_BOLD_REDdefinido en otra parte. Tengo que usar, PROMPT='%n@%m: %{%B%F{red}%}${${(%):-%~}//\//%B%F{red\}/%b%f}%b%f 'incluido el escape muy extraño de la llave de cierre (solo) después del segundo "rojo".
Dennis Williamson
Sí, utilizo los nombres de Aaron Toponce pthree.org/wp-content/uploads/2009/03/zsh_prompt, que me parecieron útiles. Además de eso, no tengo que escapar de nada, funciona según lo previsto.
Nicolas Dumazet el
0

Aquí está mi intento (basado en 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
}

La diferencia es que estoy usando una ruta de color, por lo que necesito volver a mi color original para la ruta una vez que la barra se colorea. En mi caso, el camino es normalmente amarillo, y la barra se colorea con magenta, luego vuelve a amarillo. También prefiero usar secuencias% F% f, ya que me parecen mucho más legibles.

porcelana
fuente