Что такое буфер прокрутки и прокрутки?

23

Что такое «прокрутка» и «буфер прокрутки» в таких программах, как bashи screen, и как они связаны с tty, выполняемыми программами и stdin / stdout / stderr?

Вот единственное определение «прокрутки», которое я нашел до сих пор (в вики archlinux ):

Прокрутка - это функция, которая реализована в текстовой консоли, чтобы позволить пользователю вернуться назад, чтобы просмотреть строки текста, которые прокручивались за пределы экрана. Это стало возможным благодаря буферу, созданному специально для этой цели между видеоадаптером и устройством отображения; буфер прокрутки.

Но это вызывает больше вопросов для меня:

  • Означает ли это «функция» как в «подпрограмме» или как «функция»?
  • Существует ли стандарт Unix или API для этого буфера прокрутки?
  • Какие из этих программ управляют буфером прокрутки в «стеке» программ, таких как vimзапущенные в screenзапущенном в bashзапущенном в sshзапущенном в эмуляторе терминала?

Я также использовал, screenчтобы сбросить прокрутку в файл . В этом файле было много пустого пространства вверху, и кажется, что «представление», которое показывает мой эмулятор терминала, это просто несколько нижних строк буфера.

  • Вот почему такая программа vimможет «очистить» все мое окно терминала, потому что она получает временный доступ к буферу прокрутки родительской оболочки?
  • Или vimиспользует свой собственный буфер обратной прокрутки, который каким-то образом накладывается поверх родительского буфера обратной прокрутки?
Олег
источник

Ответы:

28

Это немного сложный вопрос. Я постараюсь ответить на ваши вопросы по очереди, но сначала общее описание:

Буфер обратной прокрутки реализован вашим эмулятором терминала ( xtermKonsole, GNOME Terminal). Он содержит весь текст, отображаемый на экране, включая как стандартный вывод, так и стандартную ошибку для каждой программы, которую вы запускаете в терминале. Это полностью терминальная функциональность, позволяющая вам просматривать прошлые результаты, которые могли прокручиваться мимо вас, или проверять, что было сказано ранее.

Вы можете представить себе буфер обратной прокрутки как длинную страницу зарегистрированного вывода, а окно терминала - как окно, которое одновременно рассматривает только его часть. Если вы еще ничего не прокручивали, то вы смотрите на конец буфера. Обычно в терминале настраивается ограничение на количество отслеживаемых линий, прежде чем он начинает забывать.

Предположим, что предел составляет 1000 строк. Для первой тысячи строк вывода в вашем сеансе вы просто добавляете в буфер, и вы можете прокрутить вправо до начала вашего сеанса. Как только получится 1001-я строка вывода, первая строка в буфере будет стерта, а самая дальняя назад, которую вы можете прокрутить, станет второй строкой вашего сеанса. Буфер всегда будет содержать самые последние тысячи строк вывода, которые были отображены на вашем экране, и вы можете прокрутить вверх, чтобы просмотреть более ранние результаты в любое время.

  • Означает ли это «функция» как в «подпрограмме» или как «функция»?

    Это «функция», как в «функции». Эмулятор терминала имеет функцию, которая записывает то, что на экране, и позволяет вам прокручивать вверх и вниз в нем. Консоли в некоторых системах также поддерживают ограниченную прокрутку.

    Это становится немного сложнее, когда вы добавляете screenв микс. На этом этапе screenвыполняется эмуляция самого буфера прокрутки - вот почему вы можете копировать и вставлять из него в программу, а не только с (скажем) выбором X.

  • Существует ли стандарт Unix или API для этого буфера прокрутки?

    Краткий ответ - нет, он предоставляется только вашим терминалом. Более длинный ответ мы дойдем внизу.

  • В «стеке» программ, таких как vim, запущенный на экране, запущенном в bash, запущенном в ssh, запущенном в эмуляторе терминала, какие из этих программ управляют буфером прокрутки?

    В случае vimи bash, они не контролируют это вообще (предостережение, опять же, ниже). Ваш терминал предоставляет буфер прокрутки для всех программ внутри него, начиная с вашей оболочки. screenКак уже упоминалось выше, имитирует сам прокрутку.

  • Я также использовал экран, чтобы сбросить прокрутку в файл. В этом файле было много пустого пространства вверху, и кажется, что «представление», которое показывает мой эмулятор терминала, это просто несколько нижних строк буфера.

    Это screenвнутренний буфер. То, что на вашем экране в это время, обычно будет тем, что находится в самом низу буфера.

  • Вот почему такая программа, как vim, может «очистить» все мое окно терминала, потому что она получает временный доступ к буферу прокрутки родительской оболочки?

    Вот одна часть, где это становится намного сложнее. Практически все терминальные эмуляторы на базе X имитируют VT100, и там они поддерживают «альтернативный буфер экрана» . В отличие от обычного буфера, который используется для большинства взаимодействий терминала с последовательным выводом, альтернативный экранный буфер - это просто точный размер вашего терминала. Там нет прокрутки вверх или вниз, потому что он не больше, чем отображается.

    Идея состоит в том, чтобы позволить полноэкранному приложению делать то, что ему нужно, без вмешательства чего-либо, что у вас уже было на экране, а затем позволить вам вернуться именно к тому экрану, который у вас был раньше. Вот почему, когда вы входите, vimон заполняет весь экран, но когда вы выходите из него, вывод терминала, который вы имели ранее - все ваши прошлые запросы и вывод команд - возвращается снова. vimпереключается в буфер альтернативного экрана при его запуске и обратно в обычный буфер при выходе.

    Этот альтернативный буфер является одним из предостережений, которые я упомянул выше. Иногда программа действительно может сказать терминалу, что делать с буфером.

    screenэто другая программа, которая делает это, поэтому функция прокрутки вашего терминала обычно не работает, когда вы находитесь в сеансе экрана -  screenэмулирует сам буфер обратной прокрутки, поэтому вы должны использовать его внутреннюю функциональность для перехода к старому выводу.

  • Или vim использует свой собственный буфер обратной прокрутки, который каким-то образом накладывается поверх родительского буфера обратной прокрутки?

    Я в основном отвечал на это в предыдущем вопросе, но краткий ответ на этот конкретный вопрос заключается в том, что vimон получает свой собственный временный буфер без обратной прокрутки от терминала, а затем выполняет всю свою собственную прокрутку ваших документов внутри.

Все те исключения, которые я упомянул:

Это снова становится немного сложнее. Я сказал, что приложения не имеют никакого контроля над прокруткой и что она полностью предоставляется терминалом. В некоторых случаях с некоторыми терминалами взаимодействие ограничено. Программа распечатывает определенные escape-последовательности - если вы когда-либо использовали раскраску терминала вручную, вы уже видели, как они выглядят, - и терминал может интерпретировать их и изменять свое поведение или даже отправлять информацию в программу. Какие escape-последовательности доступны, описаны в базе данных termcap (возможность терминала) .

Некоторые терминалы поддерживают ограниченные запросы и манипулирование буфером прокрутки. Многие xtermпроизводные имеют escape-последовательности, которые направляют терминал для прокрутки его представления. Многие терминалы также поддерживают указание определенной области экрана для прокрутки, оставляя все остальные нетронутыми. Это имеет тенденцию разрушать буфер прокрутки.

Почти все терминалы поддерживают последовательности для перемещения курсора по экрану, что позволяет ncursesбиблиотеке обновлять все различные части экрана. Вы можете посмотреть на последовательности VT100, поддерживаемыеxterm . То, как они взаимодействуют с буфером прокрутки, иногда может быть немного странным, особенно в случае чего-то, что реализует свое собственное поведение прокрутки, например, lessкоманду. Вы можете получить дубликаты или пропущенные строки в вашем прокрутке, потому что lessперерисовал текст сверху, как не ожидал ваш терминал. Другие программы иногда заканчивают заполнять ваш буфер несколькими копиями всего дисплея.

Майкл Гомер
источник
1
Большое спасибо за этот отличный ответ! Это очень полно и легко понять, несмотря на сложную тему. Дополнительные детали заставляют меня хотеть узнать больше и показывают, где искать.
Олег
1
Некоторые терминалы имеют возможность неограниченной прокрутки, означает ли это, что весь прокрутку составляет ОЗУ (поэтому в какой-то момент мы получим сбой malloc или OOM на терминале), или она пытается записать на диск и загрузить с диска, как вы прокрутки? Вроде как чат-программы.
CMCDragonkai
Последовательности Escape для запросов обычно не находятся в termcap (и при этом они не находятся в terminfo, который был бы более полным).
Томас Дики
@CMCDragonkai Konsole сохраняет конечную прокрутку в памяти, но помещает бесконечный прокрутку на диск в незашифрованном виде; вы предупреждены об этом в диалоге настроек. VTE (gnome-терминал и другие) хранит прокрутку (конечную или бесконечную) на диске, сжатую и зашифрованную. Я не знаю, что делают другие эмуляторы.
egmont