Affronterò solo la domanda (1).
Il tuo problema è KEYTIMEOUT. Cito da zshzle (1):
Quando ZLE legge un comando dal terminale, può leggere una sequenza associata a un comando ed è anche un prefisso di una stringa associata più lunga. In questo caso ZLE attenderà un certo tempo per vedere se vengono digitati più caratteri e in caso contrario (o se non corrispondono più a una stringa) eseguirà l'associazione. Questo timeout è definito dal parametro KEYTIMEOUT; il suo valore predefinito è 0,4 sec. Non vi è alcun timeout se la stringa prefisso non è essa stessa associata a un comando.
Quel 0.4s è il ritardo che stai riscontrando dopo aver colpito ESC. La correzione è impostare KEYTIMEOUT fino a 0,01s in uno dei file di avvio della shell:
export KEYTIMEOUT=1
Sfortunatamente questo ha un effetto a catena: altre cose iniziano a sbagliare ...
Innanzitutto, ora esiste un problema nella modalità di comando vi: digitando ESC si blocca il cursore, quindi viene ingoiato il carattere che si digita successivamente. Questo perché ESC non è associato a nulla per impostazione predefinita nella modalità di comando vi, tuttavia ci sono widget multi-carattere che iniziano con ESC (tasti cursore!). Quindi quando premi ESC, ZLE aspetta il personaggio successivo ... e poi lo consuma.
La correzione è di associare ESC a qualcosa in modalità comando, assicurando così che qualcosa venga passato a ZLE dopo $ KEYTIMEOUT centisecondi. Ora possiamo mantenere i binding iniziando con ESC in modalità comando senza questi effetti negativi. Lego ESC al carattere di campana, che trovo ancora meno invadente di auto-inserimento (e la mia shell è messa a tacere):
bindkey -sM vicmd '^[' '^G'
Aggiornamento 2017:
Da allora ho trovato una soluzione ancora migliore per associare ESC: il undefined-key
widget. Non sono sicuro che questo widget fosse disponibile in zsh quando originariamente ho scritto questa risposta.
bindkey -M vicmd '^[' undefined-key
Problema successivo: per impostazione predefinita ci sono alcuni widget a due tasti che iniziano in ^ X nella modalità di inserimento vi; questi diventano inutilizzabili se $ KEYTIMEOUT è impostato al minimo. Quello che faccio è separare ^ X nella modalità di inserimento vi (è auto-inserimento di default); ciò consente a quei widget a due tasti di continuare a funzionare.
bindkey -rM viins '^X'
Si perde l'associazione per l'autoinserimento, ma è possibile associarlo a qualcos'altro ovviamente. (Non lo so, dal momento che non ne ho bisogno.)
L'ultimo problema (l'ho trovato finora): ci sono alcune rimanenti combinazioni di tasti predefinite che "perdiamo" a causa dell'impostazione di $ KEYTIMEOUT verso il basso, vale a dire: quelle che iniziano con ESC in modalità di inserimento vi che non sono tasti cursore. Personalmente li rilevo per iniziare invece con ^ X:
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
Aggiornamento 2018:
Si scopre che l'intera sezione sopra (dopo "Aggiornamento 2017") non è necessariamente richiesta. È possibile impostare il tasto META in modo che sia equivalente a ESC nelle mappature della tastiera usando:
bindkey -mv
È quindi possibile non separare ^ X e accedere alle combinazioni di tasti che iniziano in ESC premendo invece META come leader (ALT o OPT sulle tastiere moderne).
Se hai accesso al libro From Bash to Z Shell di Kiddle et al., L'equivalenza di ESC e META nelle combinazioni di tasti è discussa nella barra laterale del capitolo 4 alle pagine 78–79.
i
due volte per tornare alla modalità di inserimento, consiglio vivamente questa correzione!