bash viモードで、jkをマップして挿入モードを終了します


11

私はbashシェルでubuntu 16.04の新規インストールを使用しています。私がやりたいことが2つあります。

  1. 端末からvimのような動きができるようにviモードを設定します
  2. 入力して挿入モードを終了する jk

私はこれをどのように行うことができるかを別の投稿で読みましたzsh、どうすればそれを行うことができbashますか?

tl; dr

:)の後にファイルに入れbind '"jk":vi-movement-mode'ます.bashrcset -o vi

server@thinkpad:~$ tail -n 2 .bashrc
set -o vi
bind '"jk":vi-movement-mode'

詳細な説明については@grochmalの回答を参照してください


1
に再マッピングするとはどういう意味jkですか?それはキーボードの特別なキーですか?
スティーブンハリス

編集を参照してください
mbigras

最初.bashrcは、通常はすべてのシェルで呼び出されます(たとえば、からシェルを呼び出す場合vi)が.bash_profile、ログインシェルでのみ呼び出されます。ので.bashrc、適切な場所ですset -o vi。改訂された2番目の質問に対する答えはありません:-(
スティーブンハリス

どのようにbashシェルを始めていますか?.bashrcと.bash_profileの違い
the_velour_fog

回答:


10

TL; DR

bashはと同様の機能を持っているzsh「S bindkeyを通してbind、それはいくつか持っていないviようなモードをzshset -o viあなたができる後:

bind '"jk":vi-movement-mode'

同等これはzshさんは、bindkey -M <all vi modes> jk vi-movement-mode

vi-movement-mode関数は、から来ているinputrc(参照/etc/inputrc、それらのリストについては)。

全文

スティーブンハリスがコメントで指摘しているように:

  • .bashrcbash常に呼び出されます(特に他のシェルからは呼び出されません)。

  • .bash_profile ログインシェルでのみ呼び出されます(繰り返しになりますが、bashのみ)。

いくつかのディストリビューションに.bash_profileは、次のようなスケルトンが付属しています。

# ~/.bash_profile
[[ -f ~/.bashrc ]] && . ~/.bashrc

.bash_profile存在することを簡単に忘れることができるので、これは良いコンテンツです。

さて、シェルセッションでマッピングjkするEscことは、実際には不可能です。あなたがするとき:

inoremap jk <esc>

Vimでは、と入力した後jk次に入力するかどうかを確認するために少し待つ必要があることをVimが認識し、マッピングを呼び出す必要があります(または別のキーを入力してマッピングをトリガーしないでください)。補足として、これは:set timeoutlen=<miliseconds>Vimで制御されます(を参照:h timeoutlen)。

いくつかのシェルまたはX11にはそのようなタイムアウト制御がなく、複数の文字マッピングを許可していません。単一のキーのマッピングのみが許可されています(ただし、以下のサポートノートを参照してください)。

set -o vi

読み取りません。シェルで使用できる.vimrcいくつかのvi(偶数ではないvim)キーの組み合わせを模倣するだけです。同じことが言える-o emacs、それはの完全な力が付属していませんemacs


zshサポート

zsh実際にマップのタイムアウトをサポートしています。そして、あなたがマップするために、以下を使用することができますjkします<esc>

bindkey -v  # instead of set -o vi
bindkey -e jk \\e

(それは行か~/.zshrcない必要があります~/.bashrc

しかし、私はこれに反対することを勧めます。ほとんどの時間を使用vimzshています。私はinoremap jk <esc>私の中で、上記vimrcbindkey組み合わせを使用してみました。 それを使用するときzshに印刷jするのに時間がかかり過ぎて、それは私をとても悩ませました。


bashサポート

bashサポートしていますreadline bind。私はそれbashなしでコンパイルできると私は信じていreadilneます。そのため、bashがサポートされていないbind(注意が必要な)まれなシステムがあるかもしれません。にマッピングjkするに<esc>は、bash次のことを行う必要があります。

set -o vi
bind '"jk":"\e"'

(はい、それは二重レベルの引用です、それは必要です)

繰り返しになりますが、これはタイピングをjかなり面倒にします。しかし、どういうわけかzsh私のマシン上のソリューションよりも煩わしさがありません(おそらくデフォルトのタイムアウトが短いです)。


回避策(非bashおよび非zshシェルの場合)

Escキーを再マッピングする理由は、キーがキーボードからかなり離れているため、入力に時間がかかるためです。emacsみんなから借りることができるトリックCapsLockは、とにかく役に立たないキーなので、再マッピングすることです。 emacsみんなそれをリマップしますがCtrl、私たちはそれをリマップしEscます。

xev -event keyboardのキーコードを確認するために使用してみましょうCapsLock

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 8609026, (764,557), root:(765,576),
    state 0x0, keycode 66 (keysym 0xffe5, Caps_Lock), same_screen YES,
    XLookupString gives 0 bytes: 
    XmbLookupString gives 0 bytes: 
    XFilterEvent returns: False

そしての機能をチェックするにはEsc

KeyPress event, serial 25, synthetic NO, window 0x1c00001,
    root 0x496, subw 0x0, time 9488531, (571,525), root:(572,544),
    state 0x0, keycode 9 (keysym 0xff1b, Escape), same_screen YES,
    XLookupString gives 1 bytes: (1b) "
    XmbLookupString gives 1 bytes: (1b) "
    XFilterEvent returns: False

CapsLockキーコード66が非常に優れており、Escの機能は「エスケープ」と呼ばれます。今私たちはできる:

# diable caps lock
xmodmap -e "remove lock = Caps_Lock"
# make an Esc key from the keycode 66
xmodmap -e "keycode 66 = Escape"

上記はこの順序で行う必要あります。これで、ヒットCapsLockするたびにEscキーのように機能します。


トリッキーな部分は、これを設定する場所です。次~/.Xmodmapの内容のファイル:

remove lock = Caps_Lock
keycode 66 = Escape

ほとんどのディストリビューション(実際にはディスプレイマネージャーですが、単純化のためにディストリビューションと呼んでいます)で尊重されるはずですが、いくつかの~/X*ファイルを尊重しないものを見ました。そのようなディストリビューションでは、次のようなことを試してみてください:

if [ "x" != "x$DISPLAY" ]; then
    xmodmap -e "remove lock = Caps_Lock"
    xmodmap -e "keycode 66 = Escape"
fi

あなたの.bashrc

(理論的にはそれがより適切に配置されます~/.xinitrcが、ディスプレイマネージャーが尊重しない.Xmodmap場合は、絶対に尊重しません~/.xnintrc。)

エクストラ注:これはのみ再マップCapsLockEscX11セッションでは、そのためのマップは唯一の端末エミュレータで動作します。実際ttyの地図は表示されません。

参考文献と補足資料:


詳細な説明ありがとうございます。jk代わりにマッピングを除いて同じプロセスを説明してもCapsLockよろしいですか?私のosxマシンに設定しています。しかし、週末の残りの時間は私は持っていません。どうやってそれをしたのか思い出せません:)
mbigras

@mbigras-本当にbashでやりましたか?Bashにはあいまいなマップはありません。私はそれを行う方法を知っていzshますbindkey -v; bindkey -s jk \\e。しかし、それは戻って来て、あなたが必要なときに戻ってあなたをかむ何かでjkタイマーが設定できません、あなたは何も持っていないので、<leader>中をzsh
2016

私は間違いなくそれでやったzshではなくbash、それはbashで可能ではないでしょうか?
mbigras

@mbigras-待って、私は間違っていた!読んでman bash私が見つけたbindとかなり類似している作業zshs「をbindkey。答えを更新します。そこに行きます、私は使いzshすぎです。
2016

2
@ジェイソン-こんにちは、これはVi SEです。ここでは、全員がALL CAPSワードを「type word」<Esc> viwU :)で書き込みます。完成は必要ありませんん
grochmal

2

おかげで、以前の答えは、ターミナルのviのようなショートカットに〜/ .zshrcで使用しました。誰かのお役に立てば幸いです。

bindkey -v
bindkey 'jk' vi-cmd-mode

vi対応zshで「^ G」キーをバインドして「通常モード」に入るように機能する答えを探してここに来ましたが、これが機能した唯一のものです。
ダルカー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.