質問(1)のみを取り上げます。
あなたの問題はKEYTIMEOUTです。zshzle(1)から引用します。
ZLEは、端末からコマンドを読み取るときに、何らかのコマンドにバインドされているシーケンスを読み取ることができ、また、より長いバインドされた文字列のプレフィックスでもあります。この場合、ZLEは、さらに文字が入力されているかどうかを確認するために一定時間待機し、入力されていない場合(または文字列と一致しない場合)、バインディングを実行します。このタイムアウトは、KEYTIMEOUTパラメーターによって定義されます。デフォルトは0.4秒です。プレフィックス文字列自体がコマンドにバインドされていない場合、タイムアウトはありません。
その0.4秒は、ESCを押した後の遅延です。修正方法は、シェルスタートアップファイルの1つでKEYTIMEOUTを0.01に設定することです。
export KEYTIMEOUT=1
残念ながら、これはノックオン効果をもたらします。他のことがうまくいかなくなる…
まず、viコマンドモードに問題があります。ESCを入力するとカーソルがハングし、次に入力した文字が飲み込まれます。これは、viコマンドモードではESCがデフォルトでは何にもバインドされていないが、ESC(カーソルキー!)で始まる複数文字のウィジェットがあるためです。そのため、ESCを押すと、ZLEは次のキャラクターを待ちます…そしてそれを消費します。
修正方法は、コマンドモードでESCを何かにバインドし、$ KEYTIMEOUTセンチ秒後に何かがZLEに渡されるようにすることです。これで、これらの悪影響なしにコマンドモードでESCからバインディングを開始できます。ESCをベルキャラクターにバインドします。ベルキャラクターは、自己挿入よりも邪魔にならないことがわかります(シェルは沈黙しています)。
bindkey -sM vicmd '^[' '^G'
更新2017:
それ以来、ESCをバインドするためのさらに優れたソリューション、つまりundefined-key
ウィジェットを見つけました。この答えを最初に書いたときに、このウィジェットがzshで利用可能だったかどうかはわかりません。
bindkey -M vicmd '^[' undefined-key
次の問題:デフォルトでは、vi挿入モードで^ Xで始まる2つのキーウィジェットがあります。これらは、$ KEYTIMEOUTが完全に設定されていると使用できなくなります。私がしているのは、vi挿入モードで^ Xのバインドを解除することです(デフォルトでは自己挿入です)。これにより、これらの2つのキーウィジェットは引き続き機能します。
bindkey -rM viins '^X'
自己挿入のバインディングは失われますが、もちろん他の何かにバインドできます。(私は使いませんので、私はしません。)
最後の問題(私はこれまでに発見しました):$ KEYTIMEOUTを右下に設定することにより、「失う」いくつかのデフォルトのキーバインドがあります。代わりに^ Xで開始するように個人的に再バインドしました。
bindkey -M viins '^X,' _history-complete-newer \
'^X/' _history-complete-older \
'^X`' _bash_complete-word
更新2018:
上記のセクション全体(「Update 2017」以降)は必ずしも必要ではありません。以下を使用して、キーボードマッピングでMETAキーをESCと同等に設定することができます。
bindkey -mv
したがって、^ Xのバインドを解除せずに、代わりにMETAをリーダーとして押すことでESCで始まるキーバインドにアクセスすることができます(最新のキーボードではAltまたはOPT)。
Kiddleらの「From Bash to Z Shell」という本にアクセスできる場合、キーバインドでのESCとMETAの等価性については、78〜79ページの第4章の補足記事で説明しています。
i
、挿入モードに戻るために2回押す必要がある場合、この修正を強くお勧めします!