Was ist mit einer Shell im "vi" -Modus oder "emacs" -Modus gemeint?

32

Diese Frage folgt direkt aus der Antwort . In diesem Fall kann ich den folgenden Teil nicht verstehen:

In dieser Hinsicht ähnelt sein Verhalten eher dem von emacs als dem von bash (readline) / ksh / zsh emacs, weicht jedoch vom eingebetteten Ctrl-WZeileneditor des Terminaltreibers (im kanonischen Modus) ab, in dem das vorherige Wort (werase, auch in vi) gelöscht wird ).

Hier geht es um Shells und nicht um Editoren, bei denen es sich um zwei völlig verschiedene Programme handelt. Was bedeutet es zu sagen, dass sich die Shell in einem Editor-Modus befindet?

PS: Sie können Ihre Antwort auf die Voraussetzung stützen, dass ich verstehe, was eine Shell ist und wie Sie vim für die grundlegende Bearbeitung verwenden.

Aussenseiter
quelle
Hier geht es nicht um die eigentliche Kern-Shell-Funktionalität, sondern um die Zeilenbearbeitung (was Sie tun, wenn Sie einen Tippfehler machen und zurückgehen und sich selbst korrigieren).
n. 'Pronomen' m.

Antworten:

27

Im "vi" -Modus können Sie die aktuelle Shell-Eingabeaufforderung wie eine Zeile im vi-Editor bearbeiten / navigieren. Sie können es wie eine einzeilige Textdatei betrachten. Analog können Sie im "Emacs" -Modus die aktuelle Befehlszeile mit (einigen) Verknüpfungen von Emacs bearbeiten / navigieren.

Beispiel

Im vi-Modus können Sie beispielsweise Folgendes tun (in bash):

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

Im Emacs-Modus können Sie zB Ctrl+ Adrücken, um an den Anfang einer Zeile zu springen (vi: Ctrl+ [, 0oder ESC, 0). Sie können den Emacs-Modus über aktivieren set -o emacs(in bash, ksh, zsh usw.).

Zeile lesen

Viele interaktive Befehlszeilenprogramme (einschließlich Bash ) verwenden die readline- Bibliothek. Auf diese Weise können Sie konfigurieren, welcher Eingabemodus (vi oder emacs) und andere Optionen an einem Ort verwendet werden sollen, sodass jedes Programm, das readline verwendet, über genau dieselbe Bearbeitungs- / Navigationsoberfläche verfügt.

Zum Beispiel sieht meine readline Konfiguration so aus:

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

Zum Beispiel verwendet zsh / ksh meines Wissens nicht readline, sondern unterstützt auch vi / emacs-Modi, die denen von bash / readline sehr ähnlich sind.

Natürlich ist der vi / emacs-Modus in einer Kommandozeilen-Shell nur eine Teilmenge des gesamten Funktionsumfangs des Editors. Nicht alle Funktionen sind in einer Befehlszeilen-Shell sinnvoll, und einige Funktionen sind schwieriger zu unterstützen als andere.

Kanonischer Modus

Bevor vi / emacs-Modi für interaktive Befehlszeilen-Shells "erfunden" wurden, verwendete Ihre Shell nur den kanonischen Modus Ihres Terminals, der nur einen begrenzten Satz von Bearbeitungsbefehlen enthält (z. B. Ctrl+ W, um das letzte Wort zu löschen).

maxschlepzig
quelle
Angenommen, ich weiß nicht, in welchem ​​Eingabemodus ich mich befinde. Kann ich das überprüfen, indem ich einen Text eingebe und [Strg] + [A] drücke? Wenn sich der Cursor zum Anfang des Emacs bewegt, ist es sonst vi?
Limovala
2
@limovala, sollte eine gute Annäherung sein. Kommt natürlich auf deine Shell an - wenn CTL + A nicht funktioniert, besteht eine andere Möglichkeit darin, dass deine Shell keinen Bearbeitungsmodus enthält. Vielleicht implementieren einige Shells auch andere Bearbeitungsmodi. Aber in der Praxis sollte Ihre Methode gut genug sein. Sie können danach auch mit einem vi-Befehl testen, um sicherer zu sein. In bash kann man auch sowas benutzen set -o | grep 'emacs\|vi'. In zsh (wo ich vi-mode habe) funktioniert das allerdings nicht.
Maxschlepzig
bind -P gibt auch einen guten Hinweis darauf, in welchem ​​Modus man sich befindet
Paul
23

Sie werden bemerken, dass, wenn Sie catan einer Shell-Eingabeaufforderung auf einem Terminal catschreiben, was von stdin gelesen wird, und drücken a, Sie ein aEcho vom Terminal-Treiber sehen, aber catdas nicht schreiben a(sehen Sie nur eine a, die vom Terminal-Treiber wiedergegeben wird).

Wenn Sie jedoch etwas eingeben a Backspace b Enter, sehen Sie keine catAusgabe a\010b\015, sondern b\012( bund Zeilenvorschub).

Das ist , weil der Terminal - Treiber (wir reden Software im Kernel, nicht in dem Terminal - Emulator wie xterm) implementiert einen sehr einfacher Zeileneditor , wenn im kanonischen Modus. Der Terminaltreiber kann über ioctl()Systemaufrufe wie bei Verwendung des sttyBefehls konfiguriert werden . Wenn Sie beispielsweise den kanonischen Modus verlassen möchten, können Sie dies tun stty -icanon. Wenn Sie tun:

stty -icanon; cat

Dann sehen Sie gleichzeitig die echo(mit der Sie möglicherweise deaktiviert haben stty -echo) und die catAusgabe.

Dieser Editor ist ein Zeileneditor. Das heißt, der Benutzer muss eine Textzeile bearbeiten, bis diese beim Drücken von an die Anwendung gesendet wird, die das Endgerät liest Enter.

Die Bearbeitungsmöglichkeiten dieses Editors sind sehr begrenzt. In den meisten Implementierungen gibt es nur 4 Bearbeitungstasten (tatsächlich Zeichen), die auch konfiguriert werden können mit stty:

  • Löschen ( ^Hoder ^?normalerweise): Löscht das vorherige Zeichen
  • kill ( ^Unormalerweise): Leer (kill) der bisher eingegebenen Zeile
  • werase ( ^W): löscht das vorherige Wort
  • lnext ( ^V): Geben Sie das nächste Zeichen buchstäblich ein (heben Sie die spezielle Bedeutung aller oben genannten Zeichen auf)

Früher wurde angenommen, dass dieser Terminal-Treiber-Zeileneditor um ausgefeiltere Funktionen erweitert wird. Aus diesem Grund verfügt keine der frühen Shells über Befehlszeilen-Bearbeitungsfunktionen (Sie erhalten an der Shell-Eingabeaufforderung dieselben Funktionen wie bei der catoben beschriebenen Ausführung ).

Dies ist jedoch wirklich nie geschehen, möglicherweise liegt dies daran, dass verschiedene Terminals bei einigen Tastendrücken nicht die gleichen Zeichen senden. Dies hat gezeigt, dass dies nicht im Kernel-Space implementiert werden sollte.

Deshalb haben einige Shells begonnen, den kanonischen Modus des Terminal-Treibers aufzuheben und einen eigenen Zeileneditor zu implementieren. Zu dieser Zeit waren emacsund visind die beliebtesten visuellen Texteditoren mit völlig unterschiedlichen Tastenkombinationen und Bedienungsmodi. In vihaben Sie einen Modus zur Texteingabe und einen zur Bearbeitung. In wechseln emacsSie immer in den Textmodus, die Bearbeitung erfolgt jedoch durch Drücken von Tastenkombinationen ( ^bum das Zeichen rückwärts zu bewegen).

Zu dieser Zeit hatten Muscheln keinen Grund, sich eine andere Schlüsselbindung auszudenken. Das hätte die Leute frustriert, wenn sie etwas anderes gelernt hätten. Die Auswahl eines ( emacsoder vi) Stils gegenüber dem anderen wäre jedoch ein sicherer Weg gewesen, die Benutzer des anderen Editors zu entfremden .

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

Die beliebten Inline-Bearbeitungsfunktionen (vi und emacs-Modus) von ksh wurden von Software-Entwicklern bei Bell Laboratories entwickelt. Der vi-Zeilenbearbeitungsmodus von Pat Sullivan und der emacs-Zeilenbearbeitungsmodus von Mike Veach. Beide hatten die Bourne-Shell unabhängig voneinander geändert, um diese Funktionen hinzuzufügen, und beide befanden sich in Organisationen, die ksh nur verwenden wollten, wenn ksh über ihren jeweiligen Inline-Editor verfügte. Ursprünglich wurde die Idee, die Befehlszeilenbearbeitung zu ksh hinzuzufügen, in der Hoffnung abgelehnt, dass die Zeilenbearbeitung in den Terminal-Treiber verschoben wird. Als sich jedoch herausstellte, dass dies nicht in Kürze eintreten würde, wurden beide Zeilenbearbeitungsmodi in ksh integriert und als optional festgelegt, sodass sie auf Systemen deaktiviert werden konnten, die die Bearbeitung als Teil der Terminalschnittstelle bereitstellten.

Stattdessen implementierten sie beide und eine Schnittstelle, über die Benutzer zwischen beiden wählen können. kshwar höchstwahrscheinlich der erste in den frühen 80ern (Wiederverwendung von Code, der separat geschrieben wurde, um der Bourne-Shell einen vi-Modus und einen emacs-Modus hinzuzufügen, wie oben gezeigt), gefolgt von tcsh( tcshursprünglich nur emacsSchlüsselbindung, viModus wurde später hinzugefügt) und später bashund zshin den frühen 90er Jahren.

Sie wechseln zwischen den beiden Modi bash, zshoder kshmit set -o vioder set -o emacs, und mit bindkey -eoder bindkey -vin tcshoder zsh.

POSIX spezifiziert tatsächlich den viModus und nicht den emacsModus für sh(in der Geschichte hat Richard Stallman Einwände gegen POSIX erhoben, als er den emacsModus für spezifiziertesh ).

Der Standardmodus für bash, die Public Domain-Varianten von ksh(pdksh, mksh, oksh) tcshund zshist der Emacs-Modus (obwohl mit zsh, es ist, viwenn es Ihr $EDITORist vi), während in der AT & T ksh, es ist der dumme Modus, es sei denn, $EDITORoder $VISUALerwähnt vioder emacs.

kshAußerdem wurde später ein gmacsModus hinzugefügt , um Benutzern von Gosling Rechnung zu tragen emacs, die Ctrl+Tanders handelten.

Jetzt geht der Umgang mit ^Wim emacsoder im tcshEmacs-Modus wahrscheinlich dem weraseZeichen im Terminalzeilen-Editor voraus , daher können wir ihnen nicht wirklich die Schuld geben, und meine Aussage über "Abschied ..." kann als irreführend angesehen werden. Es ist nur so , dass ich finde es irritierend , wenn die Dinge mögen emacs, tcshoder infoverhalten sich anders als alles andere , wenn Sie eingeben Ctrl-W. Sie können sich vorstellen, dass ich es viel ärgerlicher fand, als einige Anwendungen ihr Fenster schlossen, als Sie tippten Ctrl-W.

Stéphane Chazelas
quelle
1
pdkshparst auch $EDITORfür viund wechselt zwischen den Modi beim Start; Ich habe das für entfernt mksh(zumal ich sowieso nur den Emacs-Modus wirklich pflege).
Mirabilos
Vielen Dank zusätzlich, vor allem mit der ausführlichen Diskussion des Verhaltens und der Geschichte der verschiedenen Muscheln. Als jemand, der regelmäßig in verschiedenen Distributionen mit Shells arbeiten muss, die ich nicht konfiguriert habe, ist dies außerordentlich hilfreich.
BryKKan
Vielen Dank für den hervorragenden historischen Kontext. Es ist schade, dass zu diesem Zeitpunkt dem Terminal-Treiber keine ausgefeilteren Inline-Bearbeitungsfunktionen hinzugefügt wurden. Programme müssen keine Bibliotheken wie Readline enthalten. Ich hatte mich auch gefragt, warum der Emacs-Modus von POSIX nicht spezifiziert wird, so dass der Link zur Begründung interessant war. (Ich teile auch Ihre Frustration mit dem ^WSchließen von Fenstern).
Anthony G - Gerechtigkeit für Monica
1
@AnthonyGeoghegan, wir würden immer noch Dinge wie zle / readline benötigen, da Dinge wie Dateiname / Befehlsvervollständigung im Terminal-Treiber nicht wirklich erledigt werden konnten.
Stéphane Chazelas