¿Mostrar cosas debajo del indicador en un indicador de shell?

21

Digamos que mi mensaje se ve así (el _ representa mi cursor)

~ % _

¿Hay alguna forma en que pueda hacer que se vea así?

~ % _
[some status]

La pregunta era originalmente sobre zsh, pero ahora tiene otras respuestas.

xenoterracida
fuente
¿Qué tal screen + buobu ?: launchpad.net/byobu , y tal vez kmandla.wordpress.com/2010/01/03/… para capturas de pantalla
Janus

Respuestas:

17

La siguiente configuración parece funcionar. El texto en la segunda línea desaparece si la línea de comando desborda la primera línea. La preexecfunción borra la segunda línea antes de ejecutar el comando; si quieres conservarlo, cambia a preexec () { echo; }.

terminfo_down_sc=$terminfo[cud1]$terminfo[cuu1]$terminfo[sc]$terminfo[cud1]
PS1_2='[some status]'
PS1="%{$terminfo_down_sc$PS1_2$terminfo[rc]%}%~ %# "
preexec () { print -rn -- $terminfo[el]; }

%los escapes se documentan en el manual de zsh ( man zshmisc).

Terminfo es una API de acceso a terminal. Zsh tiene un terminfomódulo que da acceso a la base de datos de descripción del terminal: $terminfo[$cap]es la secuencia de caracteres a enviar para ejercer la capacidad del terminal $cap, es decir, ejecutar su $capcomando. Consulte man 5 terminfo(en Linux, el número de sección puede variar en otros dispositivos) para obtener más información.

La secuencia de acciones es: mover el cursor una línea hacia abajo ( cud1), luego hacia arriba ( cuu1); guardar la posición del cursor ( sc); mueva el cursor hacia abajo una línea; imprimir [some status]; restablecer la posición del cursor. El bit hacia abajo y hacia arriba al principio solo es necesario en caso de que el mensaje esté en la línea inferior de la pantalla. La línea preexec borra la segunda línea ( el) para que no se mezcle con la salida del comando.

Si el texto en la segunda línea es más ancho que el terminal, la pantalla puede estar distorsionada. Use Ctrl+ Len una pizca para reparar.

Gilles 'SO- deja de ser malvado'
fuente
5

Aquí hay un bashequivalente de la solución zsh de Gilles. Bash no tiene un módulo terminfo nativo, pero el tputcomando (incluido terminfo) hace lo mismo.

PS1_line1='\w \$ '
PS1_line2='[some status]'

if (tput cuu1 && tput sc && tput rc && tput el) >/dev/null 2>&1
then
    PS1="
\[$(tput cuu1; tput sc)\]
\[${PS1_line2}$(tput rc)\]${PS1_line1}"
    PS2="\[$(tput el)\]> "
    trap 'tput el' DEBUG
else
    PS1="$PS1_line2 :: $PS1_line1"
fi

Si el terminal no admite una de las capacidades, recurrirá a un indicador de una línea.

La traplínea es una forma hacky de emular la preexecfunción de zsh . Consulte /superuser/175799/ para obtener más información.

EDITAR : guión mejorado basado en los comentarios de Gilles.

Jander
fuente
@Gilles: ¡Gracias por el aporte! Creo que lo tengo funcionando mejor ahora. Probé bash 4.1.5 en gnome-terminal y xterm, y bash 3.2.48 en OSX Terminal.
Jander