Czym dokładnie jest bufor przewijania i bufor przewijania?

23

Czym są „przewijanie” i „bufor przewijania” w programach takich jak bashi screeni jak odnoszą się do tty, uruchomionych programów oraz stdin / stdout / stderr?

Oto jedyna jak dotąd definicja „przewijania” (na wiki archlinux ):

Przewijanie to funkcja zaimplementowana w konsoli tekstowej, aby umożliwić użytkownikowi cofnięcie się w celu wyświetlenia linii tekstu przewijanych poza ekran. Jest to możliwe dzięki buforowi utworzonemu właśnie w tym celu między kartą wideo a urządzeniem wyświetlającym; bufor przewijania.

Ale to rodzi dla mnie więcej pytań:

  • Czy to znaczy „funkcja” jak w „podprogramie” czy w „funkcji”?
  • Czy dla tego bufora przewijania istnieje standard Unix lub interfejs API?
  • Który z tych programów steruje buforem przewijania w „stosie” programów, takich jak vimuruchamiany w uruchamiany w screenuruchamiany w bashuruchamiany w sshuruchamiany w emulatorze terminali?

Ja również wykorzystywane screendo zrzutu przewijania do pliku . Ten plik miał dużo białych znaków na górze i wydaje się, że „widok”, który pokazuje mój emulator terminala, to po prostu kilka dolnych wierszy bufora.

  • Czy dlatego taki program vimmoże „wyczyścić” całe okno terminala, ponieważ uzyskuje tymczasowy dostęp do bufora przewijania powłoki nadrzędnej?
  • Czy też vimużywa własnego bufora przewijania, który jest w jakiś sposób nałożony na nadrzędny bufor przewijania?
Oleg
źródło

Odpowiedzi:

28

To trochę skomplikowane pytanie. Spróbuję odpowiedzieć na twoje pytania kolejno, ale najpierw ogólny opis:

Bufor przewijania jest implementowany przez emulator terminala ( xterm, Konsole, GNOME Terminal). Zawiera cały tekst wyświetlony na ekranie, w tym standardowe wyjście i standardowy błąd każdego programu uruchamianego w terminalu. Jest to całkowicie terminalowa funkcjonalność, która pozwala ci spojrzeć na wcześniejsze wyniki, które mogły być przewijane obok ciebie lub sprawdzić, co powiedziałeś wcześniej.

Możesz myśleć o buforze przewijania jako o długiej stronie zapisanych danych wyjściowych, a okno terminala jako o oknie, które jednocześnie przegląda tylko jego część. Jeśli nie przewinąłeś żadnego, patrzysz na koniec bufora. Zwykle w terminalu skonfigurowany jest limit liczby linii, które śledzi, zanim zacznie zapomnieć.

Załóżmy, że limit wynosi 1000 linii. W przypadku pierwszego tysiąca wierszy danych wyjściowych sesji po prostu dołączasz do bufora i możesz przewijać w górę do samego początku sesji. Zaraz po uzyskaniu 1001-szego wiersza wyjścia pierwszy wiersz w buforze jest usuwany, a najdalej w tył, który można przewinąć, będzie drugi wiersz sesji. Bufor zawsze będzie zawierał ostatnie tysiące wierszy danych wyjściowych, które były wyświetlane na ekranie, i możesz przewinąć w górę, aby w dowolnym momencie zobaczyć wcześniejsze dane wyjściowe.

  • Czy to znaczy „funkcja” jak w „podprogramie” czy w „funkcji”?

    Jest to „funkcja” jak w „funkcji”. Emulator terminala ma funkcję, która rejestruje zawartość ekranu i umożliwia przewijanie w górę i w dół. Konsole w niektórych systemach obsługują również ograniczone przewijanie.

    To staje się nieco bardziej skomplikowane, gdy wrzucisz screendo miksu. W tym momencie screenemuluje sam bufor przewijania - dlatego możesz kopiować i wklejać go z poziomu programu, a nie tylko (powiedzmy) wybór X.

  • Czy dla tego bufora przewijania istnieje standard Unix lub interfejs API?

    Krótka odpowiedź brzmi nie, jest po prostu dostarczona przez twój terminal. Im dłuższa odpowiedź otrzymamy na dole.

  • Które z tych programów sterują buforem przewijania w „stosie” programów, takich jak vim uruchamiany na ekranie uruchamiany w bash uruchamiany w ssh uruchamiany w emulatorze terminali?

    W przypadku vimi bash, oni w ogóle tego nie kontrolują (znowu zastrzeżenie poniżej). Twój terminal zapewnia bufor przewijania dla wszystkich znajdujących się w nim programów, poczynając od powłoki. screen, jak wspomniano powyżej, sam symuluje przewijanie.

  • Użyłem również screena do zrzucenia przewijania do pliku. Ten plik miał dużo białych znaków na górze i wydaje się, że „widok”, który pokazuje mój emulator terminala, to po prostu kilka dolnych wierszy bufora.

    To jest screenwewnętrzny bufor. To, co w danym momencie znajduje się na ekranie, będzie na ogół na samym dole bufora.

  • Czy dlatego program taki jak vim może „wyczyścić” całe okno terminala, ponieważ uzyskuje tymczasowy dostęp do bufora przewijania powłoki nadrzędnej?

    Oto jedna z części, gdzie staje się znacznie bardziej skomplikowana. Praktycznie wszystkie emulatory terminali oparte na X symulują VT100, a jedną rzeczą, którą tam robią, jest obsługa „alternatywnego bufora ekranu” . W przeciwieństwie do zwykłego bufora, który jest używany do większości interakcji terminala z sekwencyjnym wyjściem, bufor alternatywnego ekranu ma dokładnie taki sam rozmiar jak terminal. Nie ma w nim przewijania w górę lub w dół, ponieważ nie jest większy niż to, co jest wyświetlane.

    Chodzi o to, aby pozwolić aplikacji pełnoekranowej robić to, co trzeba, bez ingerencji w cokolwiek, co już masz na ekranie, a następnie pozwolić ci wrócić do dokładnie tego, co miałeś wcześniej. Dlatego po wejściu vimwypełnia cały ekran, ale kiedy go opuszczasz, wówczas wyjściowe wyjście terminala, które posiadałeś wcześniej - wszystkie wcześniejsze monity i dane wyjściowe poleceń - powraca. vimprzełącza się na alternatywny bufor ekranu po uruchomieniu i wraca do normalnego bufora po wyjściu.

    Ten alternatywny bufor jest jednym z zastrzeżeń, o których wspomniałem powyżej. Czasami program naprawdę może powiedzieć terminalowi, co zrobić z buforem.

    screenjest innym programem, który to robi, dlatego funkcja przewijania terminala na ogół nie działa, gdy jesteś w sesji ekranowej -  screenemuluje sam bufor przewijania, więc musisz użyć jego wewnętrznej funkcji, aby dostać się do starego wyjścia.

  • Czy też vim używa własnego bufora przewijania, który jest w jakiś sposób nałożony na nadrzędny bufor przewijania?

    Odpowiedziałem na to głównie w poprzednim pytaniu, ale krótka odpowiedź na to konkretne pytanie jest taka, vimże pobiera swój własny bufor tymczasowy, bez przewijania, z terminala, a następnie wykonuje wewnętrzne przewijanie dokumentów.

Wszystkie te wyjątki, o których wspomniałem:

Znowu staje się nieco bardziej skomplikowane. Powiedziałem, że aplikacje nie mają żadnej kontroli nad przewijaniem i że jest on w całości obsługiwany przez terminal. W niektórych przypadkach, w przypadku niektórych terminali, interakcja jest ograniczona. Program drukuje pewne sekwencje specjalne - jeśli kiedykolwiek używałeś ręcznie kolorowania terminali, zobaczysz, jak wyglądają - i terminal może je interpretować i zmieniać jego zachowanie, a nawet wysyłać informacje do programu. Dostępne sekwencje specjalne opisano w bazie danych termcap (terminal terminal) .

Niektóre terminale obsługują ograniczone zapytania i manipulowanie buforem przewijania. Wiele xtermpochodnych ma sekwencje specjalne, które kierują terminalem do przewijania jego widoku. Wiele terminali obsługuje także określanie określonego obszaru ekranu do przewijania, pozostawiając wszystkie pozostałe nienaruszone. To zwykle powoduje uszkodzenie bufora przewijania.

Prawie wszystkie terminale obsługują sekwencje, aby przesuwać kursor po ekranie, dzięki czemu ncursesbiblioteka może aktualizować wszystkie różne części wyświetlacza. Możesz spojrzeć na obsługiwane przez VT100 sekwencjexterm . Sposób, w jaki działają one z buforem przewijania, może być czasem nieco dziwny, szczególnie w przypadku czegoś, co implementuje swoje własne zachowanie przewijania, takie jak lesspolecenie. W przewijaniu możesz skończyć ze zduplikowanymi lub brakującymi liniami, ponieważ lesszmieniłeś tekst na górze w sposób, którego nie spodziewał się twój terminal. Inne programy czasami kończą zapełnianie bufora wieloma kopiami całego wyświetlacza.

Michael Homer
źródło
1
Dziękuję bardzo za tę wspaniałą odpowiedź! Jest bardzo kompletny i łatwy do zrozumienia pomimo złożonego tematu. Dodatkowy szczegół sprawia, że ​​chcę się dowiedzieć więcej i pokazuje, gdzie szukać.
Oleg
1
Niektóre terminale mają opcję nieograniczonego przewijania, oznacza to, że całe przewijanie to pamięć RAM (więc w pewnym momencie otrzymamy awarię malloc lub OOM na terminalu), czy też próbuje zapisywać na dysk i ładować z dysku podczas zwój? Coś w rodzaju programów do czatu.
CMCDragonkai
Sekwencje specjalne dla zapytań na ogół nie są w termcap (nie są też w terminfo, co byłoby bardziej kompletne).
Thomas Dickey,
@CMCDragonkai Konsole przechowuje skończone przewijanie w pamięci, ale umieszcza nieszyfrowane przewijanie na dysku niezaszyfrowane; jesteś o tym ostrzegany w oknie dialogowym ustawień. VTE (gnome-terminal i inne) przechowuje przewijanie (skończone lub nieskończone) na dysku, skompresowane i zaszyfrowane. Nie wiem, co robią inne emulatory.
egmont