Co rozumie się przez powłokę w trybie „vi” lub „emacs”?

32

To pytanie wynika bezpośrednio z odpowiedzi . W tym przypadku nie jestem w stanie zrozumieć części, która mówi:

Pod tym względem jego zachowanie jest bliższe trybowi emacs niż w trybie bash (readline) / ksh / zsh emacs, ale odbiega od wbudowanego edytora wiersza sterownika terminala (w trybie kanonicznym), w którym Ctrl-Wusuwa poprzednie słowo (werase, również w vi ).

Mówimy tutaj o powłokach, a nie edytorach, które są dwoma zupełnie różnymi programami. Co to znaczy, że shell jest w trybie edytora?

PS: Możesz oprzeć swoją odpowiedź na założeniu, że rozumiem, co to jest powłoka i jak używać vima do podstawowej edycji.

Maniak
źródło
Nie chodzi tu o samą funkcjonalność powłoki podstawowej, ale o edycję linii (co robisz, gdy popełnisz literówkę i wrócisz i poprawisz się).
n. „zaimki” m.

Odpowiedzi:

27

W trybie „vi” możesz edytować / nawigować po bieżącym znaku zachęty powłoki, jak linia w edytorze vi. Możesz na to patrzeć jak jednowierszowy plik tekstowy. Analogicznie w trybie „emacs” możesz edytować / poruszać się po bieżącym wierszu poleceń za pomocą (niektórych) skrótów Emacsa.

Przykład

Na przykład w trybie vi możesz zrobić coś takiego (w bash):

$ set -o vi
$ ls hello world
<ESC>
bbdw # results in
$ ls world

W trybie emacs można trafić np Ctrl+ Aprzeskoczyć na początku linii (VI Ctrl+ [, 0lub ESC, 0). Możesz włączyć tryb emacsa poprzez set -o emacs(w bash, ksh, zsh itp.).

Czytaj linię

Wiele interaktywnych programów wiersza poleceń (w tym bash ) korzysta z biblioteki readline . W ten sposób możesz skonfigurować tryb wprowadzania (vi lub emacs) i inne opcje w jednym miejscu, tak aby każdy program korzystający z readline miał dokładnie ten sam interfejs edycji / nawigacji.

Na przykład moja konfiguracja readline wygląda następująco:

$ cat ~/.inputrc 
set editing-mode vi
set blink-matching-paren on

Na przykład zsh / ksh nie używa readline o ile wiem, ale obsługuje również tryby vi / emacs, które są bardzo podobne do trybu bash / readline.

Oczywiście tryb vi / emacs w powłoce wiersza poleceń jest tylko podzbiorem pełnego zestawu funkcji edytora. Nie każda funkcja ma sens w powłoce wiersza poleceń, a niektóre funkcje są bardziej skomplikowane w obsłudze niż inne.

Tryb kanoniczny

Przed wynalezieniem trybów interaktywnych powłok wiersza poleceń vi / emacs, twoja powłoka używałaby tylko trybu kanonicznego twojego terminala, który zapewnia jedynie ograniczony zestaw poleceń edycyjnych (np. Ctrl+ WDo usunięcia ostatniego słowa.

maxschlepzig
źródło
Załóżmy, że nie wiem, w którym trybie wprowadzania jestem włączony. Czy mogę to zweryfikować, wprowadzając tekst i naciskając [Ctrl] + [A]? jeśli kursor przesunie się na początek emacsa, inaczej vi?
limovala,
2
@limovala, powinno być dobrym przybliżeniem. Zależy oczywiście od powłoki - jeśli CTL + A nie działa, inną możliwością jest to, że powłoka nie zawiera żadnego trybu edycji. Być może niektóre powłoki implementują również inne tryby edycji. Ale w praktyce Twoja metoda powinna być wystarczająco dobra. Możesz również przetestować za pomocą polecenia vi, aby być bardziej pewnym. W bash możesz także użyć czegoś takiego set -o | grep 'emacs\|vi'. Jednak w Zsh (gdzie mam tryb vi) to nie działa.
maxschlepzig
bind -P da również dobre wskazanie, w którym trybie się znajduje
Paul
23

Zauważysz, że kiedy uruchamiasz się catpo znaku zachęty powłoki na terminalu, catbędąc zmuszonym do pisania na standardowe wyjście tego, co czyta ze standardowego wejścia, i naciśnij a, widzisz aecho ze strony sterownika terminala, ale cattego nie pisze a(widzisz tylko jeden a, ten powtórzony przez sterownik terminalu).

Jednak jeśli wpiszesz a Backspace b Enter, nie zobaczysz danych catwyjściowych a\010b\015, ale b\012( bi nowa linia).

Wynika to z faktu, że sterownik terminala (mówimy o oprogramowaniu w jądrze, a nie w emulatorze terminala jak xterm) implementuje bardzo prosty edytor linii w trybie kanonicznym . Sterownik terminala można skonfigurować przy użyciu ioctl()wywołań systemowych, takich jak przy użyciu sttypolecenia. Na przykład, aby wyjść z trybu kanonicznego, możesz to zrobić stty -icanon. Jeśli zrobisz:

stty -icanon; cat

Następnie zobaczysz zarówno echo(za pomocą którego można było wyłączyć stty -echo), jak i catwyjście w tym samym czasie.

Ten edytor jest edytorem liniowym. Oznacza to, że użytkownik powinien edytować jeden wiersz tekstu, dopóki nie zostanie przesłany do aplikacji czytającej urządzenie końcowe po naciśnięciu Enter.

Możliwości edytorskie tego edytora są bardzo ograniczone. W większości implementacji są tylko 4 klawisze edycji (w rzeczywistości znaki), które można również konfigurować za pomocą stty:

  • kasowanie ( ^Hlub ^?zwykle): kasowanie poprzedniego znaku
  • kill ( ^Uzwykle): pusty (kill) wprowadzony dotychczas wiersz
  • werase ( ^W): usuwa poprzednie słowo
  • lnext ( ^V): dosłownie wprowadź następny znak (anuluj specjalne znaczenie wszystkich powyższych)

W dawnych czasach sądzono, że ten edytor linii sterowników terminali zostanie rozszerzony o bardziej zaawansowane możliwości. Dlatego żadna z wczesnych powłok nie ma żadnych możliwości edycji wiersza poleceń (uzyskasz te same możliwości edycji wiersza w wierszu poleceń powłoki, gdy działasz cattak, jak to zrobiliśmy powyżej).

Jednak tak naprawdę to się nigdy nie zdarzyło, być może po części przyczyną jest bałagan z różnymi terminalami, które nie wysyłają tych samych znaków po niektórych naciśnięciach klawiszy, co pokazało, że nie powinno się tego implementować w przestrzeni jądra.

Dlatego niektóre powłoki zaczęły upuszczać tryb kanoniczny sterownika terminala i implementować własny edytor linii. W tym czasie emacsi vibyły najbardziej popularnych edytorów wizualnych z trybu pracy klucza wiążące i zupełnie innego. W vimasz jeden tryb do wprowadzania tekstu i jeden do edycji. W emacs, zawsze wchodzisz w tryb tekstowy , ale edycja odbywa się przez naciśnięcie kombinacji klawiszy (na przykład, ^baby przesunąć znak do tyłu).

W tym czasie muszle nie miały sensu wymyślać różnych kluczy. Spowodowałoby to frustrację, ponieważ ludzie musieliby się uczyć innej. Jednak wybranie jednego ( emacslub vi) stylu w stosunku do drugiego byłoby pewnym sposobem na wyobcowanie użytkowników drugiego edytora.

Według https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a :

Popularne funkcje edycji wbudowanej (tryb vi i emacs) ksh zostały stworzone przez programistów z Bell Laboratories; tryb edycji linii vi autorstwa Pat Sullivan oraz tryb edycji linii emacsa autorstwa Mike'a Veacha. Każdy z nich niezależnie zmodyfikował powłokę Bourne'a, aby dodać te funkcje, i obie działały w organizacjach, które chciały używać ksh tylko wtedy, gdy ksh miał odpowiedni wbudowany edytor. Pierwotnie pomysł dodania edycji wiersza poleceń do ksh został odrzucony w nadziei, że edycja wiersza zostanie przeniesiona do sterownika terminala. Jednak, gdy stało się jasne, że wkrótce się to nie stanie, oba tryby edycji linii zostały zintegrowane z ksh i stały się opcjonalne, aby można je było wyłączyć w systemach, które zapewniały edycję jako część interfejsu terminala.

Zamiast tego wdrożyli oba i interfejs umożliwiający użytkownikom wybór między nimi. kshbył najprawdopodobniej pierwszy na początku lat 80. (ponowne użycie kodu, który został napisany osobno w celu dodania trybu vi i trybu emacs do powłoki Bourne'a, jak pokazano powyżej), a następnie tcsh( tcshpoczątkowo tylko emacswiązanie klawiszy, vitryb został dodany później) i później bashi zshna początku lat 90.

Przełączać się między tymi dwoma trybami bash, zshalbo kshz set -o vialbo set -o emacsiz bindkey -elub bindkey -vw tcshlub zsh.

POSIX tak naprawdę określa vitryb, a nie emacstryb sh(historia mówi, że Richard Stallman sprzeciwił się POSIX określając emacstrybsh ).

Domyślny tryb dla bashdomena publiczna warianty ksh(pdksh, mksh, oksh), tcshi zshto w trybie emacs (choć zsh, to vijeśli $EDITORznaczy vi), podczas gdy w AT & T ksh, to jest głupi tryb chyba $EDITORani $VISUALwzmianki vilub emacs.

kshpóźniej dodano także gmacstryb dostosowany do użytkowników Goslinga, emacsktóre działały Ctrl+Tinaczej.

Teraz obsługa ^Ww trybie emacsa emacslub w nim tcshprawdopodobnie poprzedza weraseznak w edytorze linii terminalu, więc nie możemy ich za to winić, a moje stwierdzenie o „odejściu ...” może być postrzegane jako wprowadzające w błąd. To dlatego, że uważam, że to irytujące, gdy coś podoba emacs, tcshalbo infozachowują się odmiennie od wszystkiego innego po wpisaniu Ctrl-W. Możesz sobie wyobrazić, że było to o wiele bardziej irytujące, gdy niektóre aplikacje zaczęły zamykać swoje okno podczas pisania Ctrl-W.

Stéphane Chazelas
źródło
1
pdkshAnalizuje również $EDITORdla vii przełącza tryby upon starcie; Usunąłem to dla mksh(zwłaszcza, że ​​i tak naprawdę utrzymuję tylko tryb Emacsa).
mirabilos
Dziękuję bardzo za dodanie, szczególnie ze szczegółową dyskusją na temat zachowania i historii różnych powłok. Jako osoba regularnie wymagająca pracy w różnych dystrybucjach z powłokami, których nie skonfigurowałem, jest to niezwykle pomocne.
BryKKan
Dzięki za doskonały kontekst historyczny. Szkoda, że ​​w tym czasie do sterownika terminalu nie dodano bardziej zaawansowanych funkcji edycji bezpośredniej. Programy nie powinny zawierać bibliotek takich jak Readline. Zastanawiałem się również, dlaczego POSIX nie określa trybu Emacsa, więc link do uzasadnienia był interesujący. (Dzielę się również frustracją związaną z ^Wzamykaniem okien).
Anthony G - sprawiedliwość dla Moniki
1
@AnthonyGeoghegan, nadal potrzebowalibyśmy takich rzeczy jak zle / readline, ponieważ takich rzeczy jak uzupełnianie nazw plików / poleceń nie można naprawdę zrobić w sterowniku terminalu.
Stéphane Chazelas