我正在使用全新安装的 ubuntu 16.04 和 bash shell。我想做两件事:
- 设置 vi 模式,以便我可以从终端进行类似 vim 的操作
- 通过键入退出插入模式
jk
我读到另一个帖子如何做到这一点zsh
,我该如何做到这一点bash
?
太长了;博士
之后放入bind '"jk":vi-movement-mode'
您的.bashrc
文件中set -o vi
:)
server@thinkpad:~$ tail -n 2 .bashrc
set -o vi
bind '"jk":vi-movement-mode'
请参阅@grochmal的回答以获得更详细的解释
答案1
长话短说
Bash 具有与 throughzsh
类似的功能,但它没有像.之后您可以执行以下操作:bindkey
bind
vi
zsh
set -o vi
bind '"jk":vi-movement-mode'
这相当于zsh
的bindkey -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
你可以简单地忘记它的存在。
现在,要映射jk到Escshell 会话中,这实际上是不可能的。当你这样做时:
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
and 。zsh
我已经inoremap jk <esc>
尝试vimrc
过使用bindkey
上面的组合。 使用它时zsh
等待打印的时间太长j
,这让我很恼火。
bash 支持
bash
支持readline
bind
.我相信bash
无需编译即可编译,readilne
因此可能有一些罕见的系统不支持 bash bind
(请注意)。要映射jk
到<esc>
您bash
需要执行的操作:
set -o vi
bind '"jk":"\e"'
(是的,这是双层引用,这是必需的)
同样,这使得打字变得j
非常烦人。但不知怎的,比我机器上的解决方案更不烦人zsh
(可能默认超时更短)。
解决方法(适用于非 bash 和非 zsh shell)
重新映射按键的原因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它的功能叫“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
的不会看到地图。
参考资料和额外阅读:
答案2
谢谢,之前的回答,我在我的〜/.zshrc在我的终端中使用类似于 vi 的快捷方式。我希望它能帮助别人。
bindkey -v
bindkey 'jk' vi-cmd-mode