Comment démarrer XTerm avec une invite en bas?


12

Lorsque vous démarrez XTerm, l'invite commence à la première ligne du terminal. Lors de l'exécution des commandes, l'invite se déplace vers le bas jusqu'à ce qu'elle atteigne le bas, et à partir de là, elle y reste (même pas Shift- Page Downou la souris peut changer cela). Plutôt que d'avoir le début de la durée de vie du terminal "spécial", l'invite doit toujours être en bas du terminal. Veuillez noter que j'ai une invite sur plusieurs lignes .

Bien sûr, cela devrait sinon fonctionner comme avant (redimensionnable, défilable, pas de nouvelle ligne inutile dans la sortie, et aucune sortie disparaissant mystérieusement), donc PROMPT_COMMAND='echo;echo;...'ou similaire n'est pas une option. Idéalement, la solution ne doit pas être spécifique au shell.

Edit: La solution actuelle , tout en travaillant dans des cas simples, a quelques problèmes:

  • C'est spécifique à Bash . Une solution idéale devrait être portable à d'autres coquilles.
  • Il échoue si d'autres processus se modifientPS1 . Un exemple est virtualenv, qui ajoute (virtualenv)au début de PS1, qui disparaît ensuite toujours juste au-dessus du pli.
  • Ctrl- supprimel désormais la dernière page de l'historique.

Existe-t-il un moyen d'éviter ces problèmes, à moins de bifurquer XTerm?


D'une certaine manière, nous devons introduire des caractères vides dans le tampon de la barre de défilement de Xterm.
SHW

3
En fait, l'invite peut être facilement déplacée vers le haut à tout moment en exécutant la clearcommande.
werediver

@SHW J'espérais qu'il y avait un paramètre pour cela plutôt qu'un hack. Les hacks terminaux ont tendance à introduire des bugs très subtils dans mon expérience.
l0b0

@werediver Mais je ne veux jamais qu'il soit au top.
l0b0

1
Étant donné que seul le shell sait quand il génère une invite, toute solution doit être dans le contexte du shell. Même bifurquer XTerm n'aidera pas car XTerm ne sait pas si ce qu'on lui demande de produire est une invite ou non. Pour le terminal, l'invite du shell n'est qu'une autre séquence de caractères, pas différente de toute autre séquence de caractères qu'il pourrait recevoir.
celtschk

Réponses:


11

Si vous utilisez bash, ce qui suit devrait faire l'affaire:

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

Ou (moins efficace car il exécute une tputcommande avant chaque invite, mais fonctionne après que la fenêtre du terminal a été redimensionnée):

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

Pour éviter tputde modifier le code de sortie, vous pouvez l'enregistrer et le réinitialiser explicitement:

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

Notez que la variable retvalest locale; cela n'affecte aucune retvalvariable que vous auriez pu définir autrement dans le shell.

Étant donné que la plupart des cupcapacités des terminaux sont les mêmes \e[y;xH, vous pouvez également les coder en dur:

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

Si vous souhaitez éviter toute réinitialisation ultérieure de PS1, vous pouvez également utiliser la PROMPT_COMMANDvariable. S'il est défini, il est exécuté en tant que commande avant la sortie de l'invite. Ainsi, l'effet peut également être obtenu en

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

Bien sûr, bien que la réinitialisation PS1n'affecte pas cela, certains autres logiciels peuvent également changer PROMPT_COMMAND.


En quoi tputdiffèrent-ils de nombreuses echocommandes? (Demande par curiosité)
SHW

@ l0b0, ne mérite probablement pas de réponse séparée. J'espère que celtschk ne m'en voudra pas d'avoir édité sa réponse.
Stéphane Chazelas

'\[$(tput cup "$LINES")\]' fonctionne magnifiquement . Merci!
l0b0

Il y a un problème avec tput: il semble se réinitialiser $exit_code. Fixé en utilisant \[\e[$LINES;1H\].
l0b0

1
@ l0b0: J'ai maintenant ajouté une version utilisant tputqui préserve le code de sortie.
celtschk

4

Pour simplifier légèrement la réponse précédente, j'ai trouvé plus facile d'exécuter simplement:

tput cup $LINES

au début de .bashrcou .zshrc. Il fait juste le travail.

Avantages:

  • il ne s'imprime qu'une seule fois, lorsque vous démarrez votre shell

Les inconvénients:

  • lors de l'effacement de l'écran avec ^ L, il ne s'imprime pas et le repliement clearvers clear; tput ...n'aide pas;
  • l'invite se déplace ailleurs lorsque le terminal est redimensionné

2

Les réponses utilisant $LINESsont inutilement non portables. Comme cela est fait dans resize, vous pouvez simplement demander xtermde définir la position sur un numéro de ligne arbitrairement grand, par exemple,

tput cup 9999 0

(en supposant que vous avez une fenêtre inférieure à 10 000 lignes, sans tenir compte du défilement arrière ).

Étant donné que la chaîne ne changera pas en tant qu'effet secondaire du redimensionnement de la fenêtre, vous pouvez le calculer une fois et le coller dans votre chaîne d'invite en tant que constante, par exemple,

TPUT_END=$(tput cup 9999 0)

et ensuite

PS1="${TPUT_END} myprompt: "

selon vos préférences.

En ce qui concerne les autres processus modifiant PS1: vous devrez recalculer PS1après ces changements, pour vous assurer qu'il ressemble à ce que vous voulez. Mais la question ne contient pas suffisamment de détails pour indiquer apporter les modifications.

Et enfin: le comportement de tabulation ne correspond pas à ce type de changement, en raison des hypothèses de bash.


Qu'entendez-vous par «le comportement de complétion de tabulation ne correspond pas à ce type de changement»?
l0b0

Je pense que tu veux dire PS1="${TPUT_END} myprompt: ", ou mêmePS1="${TPUT_END}${PS1}"
l0b0

Pour ce dernier - à droite (faute de frappe de penser aux makefiles). Pour les anciens, j'ai à l'esprit que l'édition de commandes de bash repose sur la possibilité de réimprimer la ligne (avec invite), et que vous pouvez obtenir un comportement étrange lorsque cela se combine avec le défilement en raison de l'achèvement de la commande.
Thomas Dickey
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.