Ich werde nur Frage (1) ansprechen.
Ihr Problem ist KEYTIMEOUT. Ich zitiere aus zshzle (1):
Wenn ZLE einen Befehl vom Terminal liest, liest es möglicherweise eine Sequenz, die an einen Befehl gebunden ist und auch ein Präfix einer länger gebundenen Zeichenfolge ist. In diesem Fall wartet ZLE eine bestimmte Zeit, um zu sehen, ob weitere Zeichen eingegeben wurden. Wenn dies nicht der Fall ist (oder wenn sie nicht mehr mit einer Zeichenfolge übereinstimmen), wird die Bindung ausgeführt. Dieses Zeitlimit wird durch den Parameter KEYTIMEOUT definiert. Die Standardeinstellung ist 0,4 Sekunden. Es tritt keine Zeitüberschreitung auf, wenn die Präfixzeichenfolge selbst nicht an einen Befehl gebunden ist.
Diese 0,4s ist die Verzögerung, die Sie erfahren, nachdem Sie ESC geschlagen haben. Das Update besteht darin, KEYTIMEOUT in einer der Shell-Startdateien auf 0,01 Sekunden zu setzen:
export KEYTIMEOUT=1
Leider hat dies einen negativen Effekt: Andere Dinge laufen schief ...
Erstens gibt es jetzt ein Problem im vi-Befehlsmodus: Wenn Sie ESC eingeben, bleibt der Cursor hängen, und jedes Zeichen, das Sie als Nächstes eingeben, wird verschluckt. Dies liegt daran, dass ESC im vi-Befehlsmodus standardmäßig an nichts gebunden ist, es jedoch Widgets mit mehreren Zeichen gibt, die mit ESC beginnen (Cursortasten!). Wenn Sie also ESC drücken, wartet ZLE auf das nächste Zeichen ... und verbraucht es dann.
Der Fix besteht darin, ESC an etwas im Befehlsmodus zu binden und so sicherzustellen, dass das etwas nach $ KEYTIMEOUT Zentisekunden an ZLE übergeben wird. Jetzt können wir Bindungen, die mit ESC beginnen, im Befehlsmodus beibehalten, ohne diese negativen Auswirkungen. Ich binde ESC an die Glocke, die ich noch weniger aufdringlich finde als die Selbsteinfügung (und meine Shell wird stummgeschaltet):
bindkey -sM vicmd '^[' '^G'
Update 2017:
Ich habe seitdem eine noch bessere Lösung für das Binden von ESC gefunden - das undefined-key
Widget. Ich bin nicht sicher, ob dieses Widget in zsh verfügbar war, als ich diese Antwort ursprünglich schrieb.
bindkey -M vicmd '^[' undefined-key
Nächstes Problem: Es gibt standardmäßig einige Zwei-Tasten-Widgets, die im vi-Einfügemodus in ^ X beginnen. Diese werden unbrauchbar, wenn $ KEYTIMEOUT ganz nach unten gesetzt ist. Was ich tue, ist das Aufheben der Bindung von ^ X im vi-Einfügemodus (standardmäßig ist es das Einfügen selbst). Auf diese Weise können diese Zwei-Schlüssel-Widgets weiterarbeiten.
bindkey -rM viins '^X'
Sie verlieren die Bindung für die Selbsteinfügung, aber Sie können sie natürlich auch an etwas anderes binden. (Ich nicht, da ich nichts dafür habe.)
Das letzte Problem (das ich bis jetzt gefunden habe): Es gibt einige verbleibende Standard-Tastaturbelegungen, die wir "verlieren", weil wir $ KEYTIMEOUT ganz nach unten setzen: diejenigen, die mit ESC im vi-Einfügemodus beginnen und keine Cursortasten sind. Ich binde sie persönlich neu, um stattdessen mit ^ X zu beginnen:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
Update 2018:
Es stellt sich heraus, dass der gesamte obige Abschnitt (nach „Update 2017“) nicht unbedingt erforderlich ist. Es ist möglich, die META-Taste in Tastaturzuordnungen so einzustellen, dass sie der ESC-Taste entspricht:
bindkey -mv
Es ist daher möglich , ^ X nicht zu lösen und auf die Tastenkombinationen zuzugreifen, die in ESC beginnen, indem Sie stattdessen META als Führungslinie drücken (ALT oder OPT auf modernen Tastaturen).
Wenn Sie Zugriff auf das Buch From Bash to Z Shell von Kiddle et al. Haben , wird die Äquivalenz von ESC und META in Tastenkombinationen in der Seitenleiste von Kapitel 4 auf S. 78–79 erläutert.
i
zweimal drücken müssen, um in den Einfügemodus zurückzukehren, kann ich dieses Update wärmstens empfehlen !