Je vais seulement répondre à la question (1).
Votre problème est KEYTIMEOUT. Je cite zshzle (1):
Lorsque ZLE lit une commande à partir du terminal, il peut lire une séquence qui est liée à une commande et est également un préfixe d'une chaîne liée plus longue. Dans ce cas, ZLE attendra un certain temps pour voir si plus de caractères sont saisis et sinon (ou ils ne correspondent plus à une chaîne plus longue), il exécutera la liaison. Ce délai est défini par le paramètre KEYTIMEOUT; sa valeur par défaut est de 0,4 s. Il n'y a pas de délai d'expiration si la chaîne de préfixe n'est pas elle-même liée à une commande.
Ce 0,4 s est le délai que vous rencontrez après avoir appuyé sur ESC. Le correctif consiste à définir KEYTIMEOUT jusqu'à 0,01 s dans l'un des fichiers de démarrage du shell:
export KEYTIMEOUT=1
Malheureusement, cela a un effet d'entraînement: d'autres choses commencent à mal se passer…
Premièrement, il y a maintenant un problème en mode de commande vi: Taper ESC fait bloquer le curseur, puis le caractère que vous tapez ensuite est avalé. C'est parce que ESC n'est lié à rien par défaut en mode de commande vi, mais il existe des widgets à plusieurs caractères qui commencent par ESC (touches de curseur!). Ainsi, lorsque vous appuyez sur ÉCHAP, ZLE attend le personnage suivant… puis le consomme.
Le correctif consiste à lier ESC à quelque chose en mode commande, garantissant ainsi que le quelque chose est passé à ZLE après $ KEYTIMEOUT centisecondes. Nous pouvons maintenant conserver les liaisons commençant par ESC en mode commande sans ces effets néfastes. Je lie ESC au personnage de la cloche, que je trouve encore moins intrusif que l'auto-insertion (et ma coque est réduite au silence):
bindkey -sM vicmd '^[' '^G'
Mise à jour 2017:
Depuis, j'ai trouvé une meilleure solution pour lier ESC - le undefined-key
widget. Je ne sais pas si ce widget était disponible dans zsh lorsque j'ai écrit cette réponse à l'origine.
bindkey -M vicmd '^[' undefined-key
Problème suivant: Il existe par défaut des widgets à deux touches commençant par ^ X en mode d'insertion vi; ceux-ci deviennent inutilisables si $ KEYTIMEOUT est défini à fond. Ce que je fais, c'est délier ^ X en mode d'insertion vi (c'est auto-inséré par défaut); cela permet à ces widgets à deux touches de continuer à fonctionner.
bindkey -rM viins '^X'
Vous perdez la liaison pour l'auto-insertion, mais vous pouvez bien sûr la lier à autre chose. (Je ne le fais pas, car je n'en ai aucune utilité.)
Le dernier problème (que j'ai trouvé jusqu'à présent): il reste quelques raccourcis clavier par défaut que nous "perdons" en raison de la définition de $ KEYTIMEOUT vers le bas, à savoir: ceux commençant par ESC en mode d'insertion vi qui ne sont pas des touches de curseur. Je les lie personnellement pour commencer par ^ X à la place:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
Mise à jour 2018:
Il s'avère que la section entière ci-dessus (après la «mise à jour 2017») n'est pas nécessairement requise. Il est possible de définir la touche META pour qu'elle soit équivalente à ESC dans les mappages de clavier en utilisant:
bindkey -mv
Il est donc possible de ne pas dissocier ^ X, et d'accéder aux raccourcis clavier qui commencent dans ESC en appuyant à la place sur META en tant que leader (ALT ou OPT sur les claviers modernes).
Si vous avez accès au livre From Bash to Z Shell de Kiddle et al., L'équivalence de ESC et META dans les raccourcis clavier est discutée dans l'encadré du chapitre 4 aux pages 78–79.
i
deux fois pour revenir en mode insertion, je recommanderais fortement cette correction!