zsh 的命令行编辑使用的是 Zsh Line Editor(Zle),功能比 readline 强大不少,只是大量好用的功能都深埋于文档中,难得见识到。最近在看A User's Guide to the Z-Shell,虽然内容有些旧了,但依旧很有用。
首先说一点,以下内容均假定使用的是 Emacs 式键绑定。
暂停当前命令的编辑,先执行点其它命令。这个功能叫push-line
,默认绑定在Alt-q。另有一个叫做push-line-or-edit
的 widget,我把它绑过来了:
bindkey "\eq" push-line-or-edit
push-line
widget 会将当前命令行上的内容放到一个栈上,显示一个新的提示符让你来执行点别的东西。比如刚写了一个长命令的一半,却发现当前目录不对。怎么办呢?readline 里我只好先Ctrl-u,执行之后再Ctrl-y粘贴回来。偶尔会找不到之前 kill 的内容。在 Zsh 里,按下Alt-q,当前命令暂存起来,你可以执行点别的命令,再显示命令提示符时,之前 push 走的命令内容会 pop 回来。而且这个操作是可以嵌套的,因为这是一个栈。
push-line-or-edit
widget 多了个 or-edit 后缀。当输入一个if
或者for
这样的命令时,你可以写成多行,zsh 会自动判断出你的命令尚未写完,显示$PS2
提示符。这时,如果想修改之前的某一行怎么办呢?push-line-or-edit
widget 会把这些行命令变成一个不带有$PS2
提示符的多行命令,默认键绑定中,使用Ctrl-p/n或者方向键移动即可。这个就是 zsh 的多行编辑能力。如果你喜欢使用 zsh 编辑的话,可以试试zed
这个运行于 zsh 中的简单文本编辑器:
autoload zed zed some_small_text_file
按顺序执行若干条历史记录中的命令。比如我读取 3G 网卡短信使用如下的命令序列:
gnokii --smsreader gnokii --getsms SM 0 end -f sms smsmboxproc < sms > sms.mbox mutt -f sms.mbox
如果使用Ctrl-r搜索历史的话,每条命令都搜索岂不麻烦?所以有了accept-line-and-down-history
这个 widget,默认绑定于Ctrl-o。先在历史记录里找到第一条需要的命令,按下Ctrl-o,命令执行后,历史记录中的下一条就会出现了。然后接着按Ctrl-o,直到需要执行的命令序列到达最后一条,这次该按Enter了。
最后一个,你是不是经常往命令行上粘贴网址?是的话,你应该知道,网址得用引号括起来,以防止有些字符被 shell 解释了。zsh 带了个功能,可以检测出当前输入的是否是 URL,如果是的话就自动转义那些特殊字符。这样往命令行上粘贴 URL 时就不需要事先打好引号了。使用如下命令启用:
autoload -U url-quote-magic zle -N self-insert url-quote-magic