Linux Bash/Zsh 快捷键模式 Emacs/Vim


原文链接: Linux Bash/Zsh 快捷键模式 Emacs/Vim

zsh - Prompt Expansion
13 Prompt Expansion (zsh)

0=${(%):-%N}
source ${0:A:h}/zsh.d/.zplug.zsh
%N The name of the script If there is none, this is equivalent to the parameter $0

Bash 环境

多数时候我们用的是 Bash, 比如个人的 Linux 不愿去定制,远程服务器的由不得你去定制,所以就从 Bash 说起。
默认键绑定 emacs, 操作是 ctrl-x, ctrl-e

在默认的 Bash 环境下,只要在命令行中按下 ctrl-x, ctrl-e 就会把当前命令的内容调入到环境变量 $EDITOR 指示的编辑器(默认为 emacs)去编辑,编辑后保存退出就会立即执行。

如果未安装 Emacs 编辑器,在按下 ctrl-x, ctrl-e 会得到如下提示

[vagrant@localhost ~]$
-bash: emacs: command not found

如果希望使用 vi 来编辑当前命令,就需要设置 EDITOR 环境变量,比如在 .bashrc 中加入

export EDITOR=vi

那么在命令行中按下 ctrl-x, ctrl-e 使用打开 vi 来编辑当前命令。

注:Emacs 要用 ctrl-x, ctrl-c, 再回答 y, 命令保存到临时文中; 而 vi 的相应操作是 :wq, 至少这个操作上 vi 要简洁些。

可以用命令 bind -p | grep -F "\C-x\C-e 查看 ctrl-x, ctrl-e 是执行了 Readline 命令 edit-and-execute-command

$ bind -p | grep -F "\C-x\C-e"
"\C-x\C-e": edit-and-execute-command

更多:bind -p 可以显示所有的键绑定,bind -p | grep -F "\C" 可查看含 ctrl 按键的绑定。
键绑定为 vi 时,操作是正常模式下按 v 键

可以用命令 set -o vi 切换到 Vi 键绑定。切回到 emacs 键绑定用 set -o emacs。

Vi 键绑定时命令行就像是一个简单的行编辑器,Esc 在正常模式与输入模式间切换,如果要打开 Vi 来编辑当前命令只需在正常模式按下 v, 环境变量 $EDITOR 指定的编辑器(默认为 Vi ) 载入当前命令进行编辑。

如果对 Emacs 青睐有加的话,可以设置 $EDITOR 为 emacs, 这时按 v 键打开的就是 Emacs 编辑器。

Zsh 环境

快捷键设置

设置文件位置

绑定的设置可以写入 .zshrc 文件中。如果使用 oh-my-zsh ,配置还可以写入 ~/.oh-my-zsh/lib/key-bindings.zsh 中。

转换序列

在使用 bindkey 命令时,一帮第一个参数使用对应快捷键的 CSI 序列 ,如果想知道某种快捷组合键的 CSI 序列,可以有如下两种方法:

先按 Ctrl-V 然后再按组合键,如 Ctrl-A
输入 cat > /dev/null ,之后输入组合键

设置命令

前后移动一个单词

bindkey '^[^[[C' emacs-forward-word # Alt-Right
bindkey '^[^[[D' emacs-backward-word # Alt-Left
or
bindkey '^[Oc' emacs-forward-word # Ctrl-Right
bindkey '^[Od' emacs-backward-word # Ctrl-Left

同 Bash 的内置 bind 命令一样,Zsh 也有自己内置的键绑定命令 bindkey。而且也有相应的 emaces 和 vi 键绑定,切换的命令分别是 bindkey -e, 和 bindkey -v。

默认情况下,不管是 emacs 还是 vi 的按键绑定,ctrl-x, ctrl-e 和 v 键都不起作用,所以都得定制。针对两种键绑定类型分别为:

emacs 键绑定

默认的,或使用了 bindkey -e 指定为 emacs 键绑定,可以在 ~/.zshrc 中加入

autoload -z edit-command-line
zle -N edit-command-line
bindkey "^X^E" edit-command-line

source ~/.zshrc 后,便可按 ctrl-x, ctrl-e 打开 $EDITOR 指定的编辑器(默认为 vi) 来编辑当前命令

vi 键绑定

bindkey -v 切换键绑定到 vi, 在 ~/.zshrc 加入

autoload -z edit-command-line
zle -N edit-command-line
bindkey -M vicmd v edit-command-line

然后 source ~/.zshrc 后,在命令行的 vi 命令模式下按 v 键会打开$EDITOR 指定的编辑器(默认为 vi) 来编辑当前命令。

注意:在 Zsh 中,不管是 emacs 还是 vi 键绑定,未设置 $EDITOR 的话,默认都是 vi, 这一点与 Bash 是不同的。

bindkey 的几个相关命令:bindkey -l, bindkey -lL, bindkey -L, bindkey --, bindkey -a
总结

最好是设置环境变量 $EDITOR 明确指定编辑器是 emacs 还是 vi。
Bash emacs 键绑定按 ctrl-x, ctrl-e 打开编辑器载入命令,vi 键绑定按 v 键打开编辑器
Zsh 需要自行绑定按钮到 edit-command-line 命令
emacs  的保存退出命令是 ctrl-x, ctrl-c, 回答 y 退出,vi 就用 :wq 退出
配置只单单按v 键打开编辑器更容易产生误操作,也可能会与 vi 的可视模式混淆

任何情况下,不管是 Bash/Zsh, 无论何种键绑定都可以使用 fc 命令调用 EDITOR 来编辑最后一条执行的命令。

参考:

Vi mode in Bash
Zsh Line Editor
Zsh Zle Functions
Editing long commands in your shell
`