¿Cómo iniciar XTerm con un aviso en la parte inferior?

12

Al iniciar XTerm, el mensaje comienza en la primera línea del terminal. Al ejecutar comandos, el indicador se mueve hacia abajo hasta llegar al fondo y, a partir de ese momento, permanece allí (ni siquiera Shift, Page Downo el mouse puede cambiar esto). En lugar de que el inicio de la vida útil del terminal sea "especial", el mensaje siempre debe estar en la parte inferior del terminal. Tenga en cuenta que tengo un mensaje de varias líneas .

Por supuesto, de lo contrario debería funcionar como antes (redimensionable, desplazable, sin nuevas líneas innecesarias en la salida y sin salida que desaparezca misteriosamente), por lo que PROMPT_COMMAND='echo;echo;...'o similar no es una opción. La solución idealmente no debe ser específica de la carcasa.

Editar: La solución actual , mientras se trabaja en casos sencillos, tiene algunos problemas:

  • Es Bash específico . Una solución ideal debe ser portátil a otros proyectiles.
  • Se produce un error si otros procesos modificanPS1 . Un ejemplo es virtualenv, que agrega (virtualenv)al comienzo de PS1, que luego siempre desaparece justo por encima del pliegue.
  • Ctrl- lAhora elimina la última página del historial.

¿Hay alguna manera de evitar estos problemas, sin bifurcar XTerm?

l0b0
fuente
De alguna manera, necesitamos introducir caracteres en blanco en el búfer de barra de desplazamiento de Xterm.
SHW
3
En realidad, la solicitud se puede mover fácilmente hacia arriba en cualquier momento ejecutando el clearcomando.
werediver
@SHW Esperaba que hubiera una configuración para esto en lugar de un truco. Los hacks de terminales tienden a introducir errores muy sutiles en mi experiencia.
l0b0
@werediver Pero nunca quiero que esté en la cima.
l0b0
1
Como solo el shell sabe cuándo genera un mensaje, cualquier solución debe estar en el contexto del shell. Incluso bifurcar XTerm no ayudará porque XTerm no sabe si lo que se le pide que envíe sea un aviso o no. Para el terminal, el indicador de shell es solo otra secuencia de caracteres, no es diferente de cualquier otra secuencia de caracteres que pueda recibir.
celtschk

Respuestas:

11

Si se usa bash, lo siguiente debería hacer el truco:

TOLASTLINE=$(tput cup "$LINES")
PS1="\[$TOLASTLINE\]$PS1"

O (menos eficiente ya que ejecuta un tputcomando antes de cada solicitud, pero funciona después de que la ventana del terminal ha cambiado de tamaño):

PS1='\[$(tput cup "$LINES")\]'$PS1

Para evitar tputcambiar el código de salida, puede guardarlo y restablecerlo explícitamente:

PS1='\[$(retval=$?;tput cup "$LINES";exit $retval)\]'$PS1

Tenga en cuenta que la variable retvales local; no afecta a ninguna retvalvariable que podría haber definido de otra manera en el shell.

Como la cupcapacidad de la mayoría de los terminales es la misma \e[y;xH, también puede codificarla:

PS1='\[\e[$LINES;1H\]'$PS1

Si desea que sea seguro contra el reinicio posterior de PS1, también puede utilizar la PROMPT_COMMANDvariable. Si se establece, se ejecuta como comando antes de que se muestre el mensaje. Entonces el efecto también se puede lograr

PROMPT_COMMAND='(retval=$?;tput cup "$LINES";exit $retval)'

Por supuesto, si bien el reinicio PS1no afectará esto, algún otro software también podría cambiar PROMPT_COMMAND.

celtschk
fuente
¿En qué tputdifieren de muchos echocomandos? (Preguntando por curiosidad)
SHW
@ l0b0, probablemente no merece una respuesta por separado. Espero que a celtschk no le importe que edite su respuesta.
Stéphane Chazelas
'\[$(tput cup "$LINES")\]' funciona de maravilla . ¡Gracias!
l0b0
Hay un problema con tput: Parece que se reinicia $exit_code. Solucionado mediante el uso \[\e[$LINES;1H\].
l0b0
1
@ l0b0: ahora agregué una versión usando tputque conserva el código de salida.
celtschk
4

Como una ligera simplificación a la respuesta anterior, me resultó más fácil simplemente ejecutar:

tput cup $LINES

al comienzo de .bashrco .zshrc. Simplemente hace el trabajo.

Pros:

  • solo se imprime una vez, cuando comienzas tu caparazón

Contras:

  • para despejar la pantalla con ^ L, no se imprime y aliasing cleara clear; tput ...no ayuda;
  • el mensaje se mueve a otro lugar cuando se cambia el tamaño del terminal
phil pirozhkov
fuente
2

Las respuestas que utilizan $LINESson innecesariamente no portátiles. Como se hizo resize, simplemente puede solicitar xtermestablecer la posición en un número de línea arbitrariamente grande, por ejemplo,

tput cup 9999 0

(suponiendo que tiene una ventana más pequeña que 10 mil líneas, sin tener en cuenta el desplazamiento hacia atrás ).

Debido a que la cadena no cambiará como un efecto secundario de cambiar el tamaño de la ventana, puede calcular esto una vez y pegarlo en su cadena de solicitud como una constante, por ejemplo,

TPUT_END=$(tput cup 9999 0)

y después

PS1="${TPUT_END} myprompt: "

De acuerdo a sus preferencias.

En cuanto a otros procesos de modificación PS1: tendrá que volver a calcular PS1después de esos cambios, para asegurarse de que se ve como lo desea. Pero no hay suficientes detalles en la pregunta para señalar dónde hacer los cambios.

Y finalmente: el comportamiento para completar pestañas no encaja con este tipo de cambio, debido a los supuestos de bash.

Thomas Dickey
fuente
¿Qué quiere decir con "el comportamiento para completar tabulaciones no encaja con este tipo de cambio"?
l0b0
Creo que te refieres PS1="${TPUT_END} myprompt: ", o inclusoPS1="${TPUT_END}${PS1}"
l0b0
Para el último: correcto (error tipográfico al pensar en archivos make). Para el primero, tengo en cuenta que la edición de comandos de bash se basa en poder reimprimir la línea (con solicitud), y que puede obtener un comportamiento extraño cuando esto se combina con el desplazamiento debido a la finalización del comando.
Thomas Dickey