zshのviモードをbashのviモードのように動作させるにはどうすればよいですか?


24

私はzshの一般的な速度を本当に気に入っていますが、2つのことが私を悩ませています。

  1. エスケープを打ってからスラッシュを打つまでの間にちょっと待ってから、履歴検索に移動しなければなりません(スラッシュに素早くぶつかると、それは言いますzsh: do you wish to see all 514 possibilities (172 lines)
  2. なぜなら打つモードINSERT入った後aA、私は挿入モードに入った時点過去のバックスペースはできません。

2は古典的なviのようなものですが、vimスタイルの方が好きです。


誰かが二重エスケープの非常に厄介な問題に直面していてi、挿入モードに戻るために2回押す必要がある場合、この修正を強くお勧めます!
cchamberlain

ここにも良い要約があります:dougblack.io/words/zsh-vi-mode.html
jackcogdill

回答:


22

(1)。何らかの理由で、bindkeyは "/"に関して奇妙な動作をします:<esc>すぐに続くはと/解釈され<esc-/>ます。(先日この動作を観察しました。何が原因かはよくわかりません。)これがバグなのか機能なのかはわかりません。 。

このキーコンボはおそらくにバインドされ_history-complete-olderており、望ましくない結果が生成されていますbindkey -L。これが当てはまるかどうかを確認するために使用できます。

いずれにせよ、あなたが犠牲に気にしない場合は、実際の <esc-/>結合(和音として、一緒に押された)、あなたはそれがタイピングそうすることを、viのモード履歴検索コマンドに再バインドすることができます<esc>が続くが、/いずれかのタイピングで同じことを行い速度。=)

これは和音として扱われるため、最初にviコマンドモードに入る効果はありません。そのため、最初にそれを確認する必要があります。最初に、関数を定義する必要があります。それfpathを使用する場合はあなたのどこかに置き、それ以外の場合は.zshrcに入れます:

vi-search-fix() {
zle vi-cmd-mode
zle .vi-history-search-backward
}

残りは.zshrcのどちらの方法でも使用できます。

autoload vi-search-fix
zle -N vi-search-fix
bindkey -M viins '\e/' vi-search-fix

行ってもいいはずです。

(2)。次のようにバックスペースキーを修正できます。

`bindkey "^?" backward-delete-char`

また、他のviスタイルのコマンドに対して同様の動作が必要な場合:

bindkey "^W" backward-kill-word 
bindkey "^H" backward-delete-char      # Control-h also deletes the previous char
bindkey "^U" backward-kill-line            

それはの下で^[/はありませんでした\e/が、それらは両方ともエスケープと言う有効な方法です。変更は完全に機能します。これでもっと完全に遊んでいるので、bshに比べてzshのviモードが悪いように見えます(少なくとも、デフォルトでは完全には構成されていません)。この1つの例は、検索履歴の後に挿入モードになることです。次の検索項目を見つけるには、コマンドモードに戻ってnを押す必要があります。
チャス。オーウェンス

1
まあ、他の例があるかどうかはわかりませんが、あなたが言及しているのは、zshではなく私のせいです。=)起こったことは、vi挿入モードでvi-cmdモードエディターコマンドをバインドしたことです。このコマンドは、シェルが既にcmdモードであると想定し、それに応じて動作します。最初に「cmdモードに入る」コマンドを呼び出してから実行するエディターコマンドを記述する必要があります.vi-history-search-backward。それを書き、答えを編集します。今日またチェックしてください。
マーシャルユーバンクス

OK、答えを更新しました。やってみて。
マーシャルユーバンクス

(2)についてはbindkey | grep <searchterm>、いずれかの用語を使用すると、すべての接頭辞がになりvi-ます。bindkey接頭辞が付いていないコマンドを設定する必要がありますvi-か?
adam_0

1
ありがとうございました。これらのハック(および以下のwjvのハックも)により、zshのviモードはほとんど使用不可能から優れたものになります。投票できるように、スーパーユーザーアカウントを作成しました。:-)
15年

14

質問(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章の補足記事で説明しています。


ありがとうございました。これらのハック(および上記のマーシャリングのハックも)により、zshのviモードはほとんど使用できないモードから優れたモードになります。投票できるように、スーパーユーザーアカウントを作成しました。:-)
15年

1
ありがとう!この後も、zsh機能のコアビットを使用可能にするために、基本的にハックと回避策が必要なのは少し心配です!
wjv
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.