Qu'est-ce que le défilement et le tampon de défilement?

23

Que sont "scrollback" et "scrollback buffer" dans des programmes comme bashet screen, et comment sont-ils liés au tty, aux programmes en cours d'exécution et à stdin / stdout / stderr?

Voici la seule définition de "scrollback" que j'ai trouvée jusqu'à présent (dans le wiki archlinux ):

Le défilement est une fonction implémentée dans une console de texte pour permettre à l'utilisateur de revenir en arrière pour afficher les lignes de texte qui ont défilé hors de l'écran. Ceci est rendu possible par un tampon créé spécialement à cet effet entre l'adaptateur vidéo et le périphérique d'affichage; le tampon de défilement.

Mais cela me pose plus de questions:

  • Cela signifie-t-il "fonction" comme dans "sous-programme" ou comme "fonction"?
  • Existe-t-il une norme Unix ou une API pour ce tampon de défilement?
  • Dans une "pile" de programmes, comme vimlancé dans screenlancé dans bashlancé dans sshlancé dans un émulateur de terminal, lesquels de ces programmes contrôlent le tampon de défilement?

J'ai également utilisé screenpour vider le défilement dans un fichier . Ce fichier avait beaucoup d'espace blanc en haut, et il semble que la "vue" que mon émulateur de terminal me montre est simplement les quelques dernières lignes du tampon.

  • Est-ce la raison pour laquelle un programme comme vim"effacer" toute ma fenêtre de terminal, car il obtient un accès temporaire au tampon de défilement du shell parent?
  • Ou vimutilise-t-il son propre tampon de défilement qui est en quelque sorte superposé au-dessus du tampon de défilement parent?
Oleg
la source

Réponses:

28

C'est une question un peu compliquée. Je vais essayer de répondre à vos questions tour à tour, mais d'abord une description générale:

Le tampon de défilement est implémenté par votre émulateur de terminal ( xterm, Konsole, GNOME Terminal). Il contient tout le texte qui a été affiché à l'écran, y compris la sortie standard et l'erreur standard de chaque programme que vous exécutez dans le terminal. C'est entièrement une fonctionnalité de terminal pour vous permettre de regarder les sorties passées qui peuvent avoir défilé devant vous ou pour vérifier ce que quelque chose a dit plus tôt.

Vous pouvez considérer le tampon de défilement comme une longue page de sortie consignée et votre fenêtre de terminal comme une fenêtre n'en regardant qu'une partie à tout moment. Si vous n'avez pas fait défiler vers le haut, ce que vous regardez est la fin du tampon. Habituellement, il y aura une limite configurée dans le terminal du nombre de lignes qu'il garde en mémoire avant de commencer à oublier.

Supposons que cette limite soit de 1 000 lignes. Pour les mille premières lignes de sortie de votre session, il vous suffit de les ajouter au tampon et vous pouvez faire défiler jusqu'au début de votre session. Dès que vous obtenez la 1001e ligne de sortie, la première ligne du tampon est effacée et le plus en arrière que vous pouvez faire défiler sera la deuxième ligne de votre session. Le tampon contiendra toujours les milliers de lignes de sortie les plus récentes qui ont été affichées sur votre écran, et vous pouvez faire défiler vers le haut pour regarder la sortie précédente à tout moment.

  • Cela signifie-t-il "fonction" comme dans "sous-programme" ou comme "fonction"?

    C'est "fonction" comme dans "fonction". L'émulateur de terminal dispose d'une fonctionnalité qui enregistre ce qui est à l'écran et vous permet de faire défiler vers le haut et vers le bas. Les consoles de certains systèmes prennent également en charge le défilement limité.

    Cela devient un peu plus compliqué une fois que vous vous lancez screendans le mix. À ce stade, screenémule le tampon de défilement lui-même - c'est pourquoi vous pouvez copier et coller à partir de celui-ci dans le programme, plutôt que seulement avec (disons) la sélection X.

  • Existe-t-il une norme Unix ou une API pour ce tampon de défilement?

    La réponse courte est non, elle est simplement fournie par votre terminal. La réponse plus longue, nous arriverons au bas.

  • Dans une "pile" de programmes, tels que vim lancé en écran lancé en bash lancé en ssh lancé en émulateur de terminal, lesquels de ces programmes contrôlent le tampon de défilement?

    Dans le cas de vimet bash, ils ne le contrôlent pas du tout (mise en garde, encore une fois, ci-dessous). Votre terminal fournit le tampon de défilement pour tous les programmes qu'il contient, à partir de votre shell. screen, comme mentionné ci-dessus, simule le défilement lui-même.

  • J'ai également utilisé l'écran pour sauvegarder le défilement dans un fichier. Ce fichier avait beaucoup d'espace blanc en haut, et il semble que la "vue" que mon émulateur de terminal me montre soit simplement les quelques dernières lignes du tampon.

    Il s'agit screendu tampon interne de. Ce qui est sur votre écran à ce moment-là sera généralement ce qui est tout en bas du tampon.

  • Est-ce la raison pour laquelle un programme comme vim peut "effacer" toute ma fenêtre de terminal, car il obtient un accès temporaire au tampon de défilement du shell parent?

    Voici une partie où cela devient beaucoup plus complexe. Presque tous les émulateurs de terminaux basés sur X simulent un VT100, et une chose qu'ils font là-bas est de prendre en charge un "tampon d'écran alternatif" . Contrairement au tampon ordinaire utilisé pour la plupart des interactions de terminal avec une sortie séquentielle, le tampon d'écran alternatif est juste la taille exacte de votre terminal. Il n'y a pas de défilement vers le haut ou vers le bas car il n'est pas plus grand que ce qui est affiché.

    L'idée est de permettre à une application plein écran de faire ce qu'elle doit faire sans être gêné par tout ce que vous aviez déjà à l'écran, puis de vous laisser revenir exactement à l'affichage que vous aviez auparavant. C'est pourquoi lorsque vous entrez, vimil remplit tout l'écran, mais lorsque vous le quittez, la sortie du terminal que vous aviez auparavant - toutes vos invites et sorties de commande passées - revient à nouveau. vimbascule dans le tampon d'écran alternatif au démarrage et revient au tampon normal à la sortie.

    Ce tampon alternatif est l'une des mises en garde que j'ai mentionnées ci-dessus. Parfois, le programme a vraiment la capacité de dire au terminal quoi faire avec le tampon.

    screenest un autre programme qui fait cela, c'est pourquoi la fonctionnalité de défilement de votre terminal ne fonctionne généralement pas lorsque vous êtes dans une session d'écran -  screenémule le tampon de défilement lui-même, vous devez donc utiliser ses fonctionnalités internes pour accéder à l'ancienne sortie.

  • Ou est-ce que vim utilise son propre tampon de défilement qui est en quelque sorte superposé au-dessus du tampon de défilement parent?

    J'ai principalement répondu à cela dans la question précédente, mais la réponse courte à cette question particulière est que vimle terminal obtient son propre tampon temporaire, sans retour en arrière, puis effectue tout son propre défilement de vos documents en interne.

Toutes ces exceptions que j'ai mentionnées:

Cela devient encore un peu plus compliqué. J'ai dit que les applications n'avaient aucun contrôle sur le défilement et qu'il était entièrement fourni par le terminal. Dans certains cas, avec certains terminaux, l'interaction est limitée. Le programme imprime certaines séquences d'échappement - si vous avez déjà utilisé la coloration du terminal manuellement, vous aurez vu à quoi elles ressemblent - et le terminal peut les interpréter et changer son comportement, ou même renvoyer des informations au programme. Les séquences d'échappement disponibles sont décrites dans la base de données termcap (capacité de terminal) .

Certains terminaux prennent en charge une interrogation et une manipulation limitées du tampon de défilement. De nombreux xtermdérivés ont des séquences d'échappement qui dirigent le terminal pour faire défiler sa vue. De nombreux terminaux prennent également en charge la spécification d'une zone particulière de l'écran à faire défiler, laissant tout le reste intact. Cela a tendance à briser le tampon de défilement.

Presque tous les terminaux prennent en charge les séquences pour déplacer le curseur sur l'écran, ce qui permet à la ncursesbibliothèque de mettre à jour toutes les différentes parties de l'affichage. Vous pouvez consulter les séquences VT100 prises en charge parxterm . La façon dont ceux-ci interagissent avec le tampon de défilement peut parfois être un peu étrange, en particulier dans le cas de quelque chose qui implémente son propre comportement de défilement, comme la lesscommande. Vous pouvez vous retrouver avec des lignes dupliquées ou manquantes dans votre défilement, car lessredessiné le texte par-dessus d'une manière que votre terminal ne s'attendait pas. D'autres programmes finissent parfois par remplir votre tampon avec plusieurs copies de leur affichage complet.

Michael Homer
la source
1
Merci beaucoup pour cette excellente réponse! Il est très complet et facile à comprendre malgré le sujet complexe. Le détail supplémentaire me donne envie d'en savoir plus et me montre où chercher.
Oleg
1
Certains terminaux ont une option de défilement illimité, cela signifie-t-il que le défilement entier est RAM (donc à un moment donné, nous obtiendrons une défaillance malloc ou OOM sur le terminal), ou essaie-t-il d'écrire sur le disque et de charger à partir du disque comme vous faire défiler? Un peu comme des programmes de chat.
CMCDragonkai
Les séquences d'échappement pour les requêtes ne sont généralement pas dans termcap (ni dans terminfo, ce qui serait plus complet).
Thomas Dickey
@CMCDragonkai Konsole conserve le défilement fini en mémoire, mais place le défilement infitnite sur le disque non chiffré; vous en êtes averti dans sa boîte de dialogue des paramètres. VTE (gnome-terminal et autres) stocke le scrollback (fini ou infini) sur disque, compressé et crypté. Je ne sais pas ce que font les autres émulateurs.
egmont