在 zsh 里同时用上 Vim 和 Emacs 快捷键
编辑很多开发者在终端里用 zsh 的时候,会习惯性地打开 bindkey -v
,进入 vi 模式。这样做的好处很明显:命令行也能像 Vim 一样分成 普通模式和插入模式,用 h/j/k/l
移动光标,w/b
按词跳转,甚至可以 dd
删除一整行,yy/p
来复制粘贴——对于重度 Vim 用户来说非常顺手。
问题是,一旦切到 vi 模式,zsh 默认的 Emacs-style 快捷键(Ctrl-A
跳到行首、Ctrl-E
到行尾、Ctrl-U
清空整行等等)就全都失效了。
这些快捷键虽然简单,却是很多人输入命令时的肌肉记忆,一下子丢掉会非常别扭。
好在 zsh 的键绑定系统很灵活,我们完全可以把常用的 Emacs-style 操作重新绑定回 vi 插入模式,于是就有了一个“混合流派”:
在普通模式下享受 Vim 的强大编辑能力,在插入模式下继续用熟悉的 Emacs-style 快捷键。
怎么做
zsh 把快捷键分成不同的 keymap:
vicmd
—— 普通模式viins
—— 插入模式
我们只要在 viins
里加上自己想要的绑定即可。
在 ~/.zshrc
里加上:
# 启用 vi 模式
bindkey -v
export KEYTIMEOUT=1 # 缩短 ESC 切回普通模式的延迟
# 保留常用 Emacs-style 快捷键(插入模式)
bindkey -M viins '^A' beginning-of-line # Ctrl-A 跳到行首
bindkey -M viins '^E' end-of-line # Ctrl-E 跳到行尾
bindkey -M viins '^B' backward-char # Ctrl-B 光标左移
bindkey -M viins '^F' forward-char # Ctrl-F 光标右移
bindkey -M viins '^U' kill-whole-line # Ctrl-U 清空整行
bindkey -M viins '^K' kill-line # Ctrl-K 删除到行尾
bindkey -M viins '^W' backward-kill-word # Ctrl-W 删除前一个单词
bindkey -M viins '^Y' yank # Ctrl-Y 粘贴上一次删除
bindkey -M viins '^_' undo # Ctrl-_ 撤销(有时要 Ctrl-Shift-- 才能触发)
bindkey -M viins '^R' history-incremental-search-backward # Ctrl-R 搜索历史
同时修复一些常见问题:
# Backspace / Delete 兼容
bindkey -M viins '^?' backward-delete-char
bindkey -M viins '^H' backward-delete-char
bindkey -M viins '^[[3~' delete-char
# 方向键和 Home/End
bindkey -M viins '^[[A' up-line-or-history
bindkey -M viins '^[[B' down-line-or-history
bindkey -M viins '^[[C' forward-char
bindkey -M viins '^[[D' backward-char
bindkey -M viins '^[[H' beginning-of-line
bindkey -M viins '^[[F' end-of-line
这样一来,插入模式下就能继续用熟悉的 Emacs-style 快捷键,而普通模式下依然保留 Vim 的强大命令。
我的配置:https://gist.github.com/mkdir700/3c4482f03009e6c30b5ba29ffa82d2a5
实际体验
配置好之后,你会得到一种非常自然的体验:
- 普通模式:
可以用0/^/$
精确跳转,dw
删除一个单词,yy/p
复制粘贴,dd
删除整行……完全是 Vim 的手感。 - 插入模式:
又能用回Ctrl-A/E
、Ctrl-U/K
、Ctrl-B/F
这些简洁直接的操作,不需要刻意去记新的命令。
两套习惯不冲突,反而互补。简单的场景下用 Emacs-style,复杂编辑直接切到普通模式,一点也不违和。
调试小技巧
-
确认某个按键序列
cat -v
按下有问题的按键,就能看到它发出的序列(例如 Backspace 可能是
^?
或^H
),再对应加到bindkey
就行。 -
查看当前绑定
bindkey -M viins
总结
zsh 的 vi 模式让命令行具备了 Vim 的强大编辑能力,但默认会牺牲掉一些常用的 Emacs-style 快捷键。
通过在 viins
keymap 里补回这些绑定,我们可以兼得两派的优势:普通模式下用 Vim,插入模式下保留 Emacs-style。
如果你是一个习惯了 Vim,又不想放弃 Ctrl-A/E/U/K
这些经典操作的人,这套混合配置绝对值得一试。
- 0
- 0
-
分享