Come avviare XTerm con prompt in fondo?


12

All'avvio di XTerm il prompt inizia dalla prima riga del terminale. Durante l'esecuzione dei comandi il prompt si sposta verso il basso fino a quando non raggiunge il fondo, e da quel momento in poi rimane lì (nemmeno Shift- Page Downo il mouse può cambiarlo). Invece che l'inizio della durata del terminale sia "speciale", il prompt dovrebbe essere sempre nella parte inferiore del terminale. Si prega di notare che ho un prompt multilinea .

Ovviamente, altrimenti dovrebbe funzionare come prima (ridimensionabile, scorrevole, nessuna nuova riga non necessaria nell'output e nessuna output che scompare misteriosamente), quindi PROMPT_COMMAND='echo;echo;...'o simile non è un'opzione. Idealmente, la soluzione non dovrebbe essere specifica per shell.

Modifica: la soluzione corrente , sebbene funzioni in casi semplici, presenta alcuni problemi:

  • È specifico di Bash . Una soluzione ideale dovrebbe essere portatile per altre shell.
  • Non riesce se altri processi vengono modificatiPS1 . Un esempio è virtualenv, che aggiunge (virtualenv)alla partenza della PS1, che poi scompare sempre appena sopra la piega.
  • Ctrl- lora rimuove l'ultima pagina della cronologia.

Esiste un modo per evitare questi problemi, a parte il fork di XTerm?


In qualche modo, dobbiamo introdurre caratteri vuoti nel buffer della barra di scorrimento di Xterm.
SHW

3
In realtà, il prompt può essere facilmente riportato in alto in qualsiasi momento eseguendo il clearcomando.
Werediver,

@SHW Speravo che ci fosse un'impostazione piuttosto che un hack. Gli hack del terminale hanno la tendenza a introdurre bug molto sottili nella mia esperienza.
l0b0

@werediver Ma non voglio mai che sia al top.
l0b0

1
Poiché solo la shell sa quando genera un prompt, qualsiasi soluzione deve trovarsi nel contesto della shell. Anche il fork di XTerm non aiuta perché XTerm non sa se ciò che viene richiesto di generare è un prompt o meno. Per il terminale, il prompt della shell è solo un'altra sequenza di caratteri, non diversa da qualsiasi altra sequenza di caratteri che potrebbe ricevere.
Celtschk,

Risposte:


11

Se si utilizza bash, il seguente dovrebbe fare il trucco:

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

Oppure (meno efficiente in quanto esegue un tputcomando prima di ogni prompt, ma funziona dopo il ridimensionamento della finestra del terminale):

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

Per impedire la tputmodifica del codice di uscita, è possibile salvarlo e ripristinarlo esplicitamente:

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

Si noti che la variabile retvalè locale; non influisce su alcuna retvalvariabile che potrebbe essere stata definita diversamente nella shell.

Poiché la maggior parte delle cupfunzionalità dei terminali è la stessa \e[y;xH, è possibile anche codificarla:

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

Se vuoi che sia sicuro contro il successivo ripristino di PS1, puoi anche utilizzare la PROMPT_COMMANDvariabile. Se impostato, viene eseguito come comando prima che venga emesso il prompt. Quindi l'effetto può anche essere raggiunto da

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

Naturalmente, mentre il ripristino PS1non influisce su questo, alcuni altri software potrebbero anche cambiare PROMPT_COMMAND.


Quanto tputdifferiscono da molti echocomandi? (Chiedendo per curiosità)
SHW

@ l0b0, probabilmente non merita una risposta separata. Spero che a celtschk non dispiaccia di aver modificato la sua risposta.
Stéphane Chazelas,

'\[$(tput cup "$LINES")\]' funziona magnificamente . Grazie!
l0b0

C'è un problema con tput: sembra reimpostare $exit_code. Risolto usando \[\e[$LINES;1H\].
l0b0

1
@ l0b0: ora ho aggiunto una versione tputche utilizza il codice di uscita.
Celtschk,

4

Come leggera semplificazione della risposta precedente, ho trovato più semplice eseguire:

tput cup $LINES

all'inizio di .bashrco .zshrc. Fa solo il lavoro.

Professionisti:

  • stampa solo una volta, quando si avvia la shell

Contro:

  • quando si pulisce schermo con ^ L, non stampa e aliasing clearper clear; tput ...non aiuta;
  • il prompt si sposta altrove quando il terminale viene ridimensionato

2

Le risposte utilizzate $LINESsono inutilmente non portatili. Al termine resize, puoi semplicemente chiedere xtermdi impostare la posizione su un numero di riga arbitrariamente grande, ad es.

tput cup 9999 0

(supponendo che tu abbia una finestra più piccola di 10 mila righe, trascurando lo scrollback ).

Poiché la stringa non cambierà come effetto collaterale del ridimensionamento della finestra, puoi calcolarla una volta e incollarla nella stringa del prompt come costante, ad es.

TPUT_END=$(tput cup 9999 0)

e più tardi

PS1="${TPUT_END} myprompt: "

secondo le tue preferenze.

Per quanto riguarda la modifica di altri processi PS1: dovrai ricalcolare PS1dopo tali modifiche, per assicurarti che appaia come desideri. Ma non ci sono abbastanza dettagli nella domanda per indicare dove apportare le modifiche.

E infine: il comportamento per il completamento delle schede non si adatta a questo tipo di cambiamento, a causa dei presupposti di bash.


Che cosa intendi con "il comportamento per il completamento delle schede non si adatta a questo tipo di modifica"?
l0b0,

Penso che intendi PS1="${TPUT_END} myprompt: ", o addiritturaPS1="${TPUT_END}${PS1}"
l0b0,

Per quest'ultimo - giusto (refuso dal pensare ai makefile). Per prima cosa, ho in mente che la modifica dei comandi di bash si basa sulla capacità di ristampare la linea (con prompt) e che è possibile ottenere un comportamento strano quando questo si combina con lo scorrimento a causa del completamento del comando.
Thomas Dickey,
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.