在 bash vi 模式下,映射 jk 以退出插入模式
我正在使用帶有 bash shell 的全新安裝的 ubuntu 16.04。我想做兩件事:
- 設置 vi 模式,這樣我就可以從終端進行類似 vim 的動作
- 通過鍵入退出插入模式
jk
我在另一篇文章中讀到如何
zsh
做到這一點,我該怎麼做bash
?tl;博士
之後放入
bind '"jk":vi-movement-mode'
你的.bashrc
文件set -o vi
:)server@thinkpad:~$ tail -n 2 .bashrc set -o vi bind '"jk":vi-movement-mode'
請參閱@grochmal 的答案以獲得更詳細的解釋
TL; 博士
Bash 具有與
zsh
’sbindkey
through類似的功能bind
,但它沒有vi
像zsh
. 之後set -o vi
你可以這樣做:bind '"jk":vi-movement-mode'
相當於
zsh
’sbindkey -M <all vi modes> jk vi-movement-mode
vi-movement-mode
函式來自inputrc
(查看它們的/etc/inputrc
列表)。全文
正如斯蒂芬哈里斯在他的評論中指出的那樣:
.bashrc
總是被呼叫bash
(尤其是不被其他 shell 呼叫)。.bash_profile
僅在登錄 shell 上呼叫(同樣,僅 bash)。一些發行版帶有
.bash_profile
如下所示的骨架:# ~/.bash_profile [[ -f ~/.bashrc ]] && . ~/.bashrc
這是一個很好的內容,
.bash_profile
因為您可以簡單地忘記它的存在。現在,要映射
j``k
到Esc
shell 會話中,這是不可能的。當你這樣做時:inoremap jk <esc>
在 Vim 中,在你鍵入 之後
j
,Vim 知道它需要稍等片刻,看看你是否鍵入k
下一個,它應該呼叫映射(或者你鍵入另一個鍵並且不應該觸發映射)。作為附錄,這是由:set timeoutlen=<miliseconds>
Vim 控制的(請參閱 參考資料:h timeoutlen
)。一些 shell 或 X11 沒有這樣的超時控制,並且不允許多個字元映射。只允許映射單個鍵(但請參閱下面的支持說明。)。
set -o vi
不讀
.vimrc
,它只是模仿一些vi
(甚至不是vim
)可以在shell中使用的組合鍵。差不多可以這麼說-o emacs
,它並沒有自帶全部威力emacs
。zsh 支持
zsh
實際上支持地圖超時。您可以使用以下內容映射jk
到<esc>
:bindkey -v # instead of set -o vi bindkey -e jk \\e
(那將需要
~/.zshrc
不去~/.bashrc
)然而,我建議不要這樣做。我大部分時間都在使用
vim
。zsh
我有inoremap jk <esc>
,vimrc
我確實嘗試過使用bindkey
上面的組合。zsh
使用時等待列印的時間太長j
,這讓我很惱火。bash 支持
bash
支持readline
bind
。我相信bash
可以在沒有的情況下進行編譯,readilne
因此可能會有一些罕見的系統不支持 bashbind
(請注意)。要映射jk
到<esc>
,bash
您需要執行以下操作:set -o vi bind '"jk":"\e"'
(是的,這是雙重引用,需要)
同樣,這使打字
j
很煩人。但不知何故比zsh
我機器上的解決方案更煩人(可能預設超時更短)。解決方法(對於非 bash 和非 zsh shell)
重新映射鍵的原因
Esc
是它位於鍵盤上很遠的地方,並且鍵入它需要時間。可以從這些emacs
傢伙那裡借鑒的一個技巧是重新映射CapsLock
,因為無論如何它都是無用的鍵。emacs
伙計們將其重新映射到,Ctrl
但我們會將其重新映射到Esc
.讓我們
xev -event keyboard
來檢查一下 keycodeCapsLock
: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
是keycode 66,Esc
功能叫“Escape”。現在我們可以這樣做:# 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
。)額外說明:這僅在 X11 會話中重新映射
CapsLock
,Esc
因此該映射僅適用於終端仿真器。實際tty
的將看不到地圖。參考資料和額外閱讀: