2.4 程序名、命令名补全

不带选项的程序名、命令名补全几乎跟文件名补全一样,让我们来看一个例子。要是你看过《黑客帝国》这部电影,那么下面的画面你应该会很熟悉。当我输入

xiaodong@codeland:~$ cmat

后按 Tab,bash 立即为我自动补全了 cmatrix 命令。

xiaodong@codeland:~$ cmatrix

而当我在输入

xiaodong@codeland:~$ cma

后按 Tab,bash 为我提供了一个备选补全列表。

xiaodong@codeland:~$ cma
cmake        cmake-gui    cmapcube     cmark        cmark-gfm    cmatrix

此时,需要再输入 t 才能完成补全。

xiaodong@codeland:~$ cmat

如果我在仅仅输入 c (命令开头的第一个字符)

xiaodong@codeland:~$ c

后便按 Tab,这时 bash 询问我:“Display all 474 possibilities? (y or n)” (是否显示所有 474 个补全列表项目) 按 y 予以显示。按 n 则不显示。

xiaodong@codeland:~$ c
Display all 474 possibilities? (y or n)

因为可供自动补全的列表项目太多,一屏已经显示不下了,所以 bash 使用 more 这个页面查看程序来呈现。现在按 Space (空格键) 可以翻页,如果想退出,那么按 q 即可。如图 2.3 所示。

命令自动补全备选列表

图 2.3: 命令自动补全备选列表

除了直接补全命令名之外,Shell 也能自动补全程序的子命令,例如:git status 中的 status 以及命令的选项。不过,bash 需要安装一个单独的 bash-completion 包;而 zsh 因为内置了对此功能的支持,所以不需要额外的包。

bash-completion 的源代码位于 GitHub 上,在此可以了解如何对其安装和配置。例如:

在 Debian 中,我们可以通过执行

xiaodong@codeland:~# apt install bash-completion

来安装它。

在 CentOS 上,除了安装 bash-completion 外,我推荐把 bash-completion-extras 也装上。

xiaodong@codeland:~# yum install bash-completion bash-completion-extras

而在 Arch Linux 上,则可以执行

xiaodong@codeland:~# pacman -S bash-completion

进行安装。

要配置 bash-completion,则只需要将下面这行指令加入 ~/.bashrc (个人) 或 /etc/bash.bashrc (全局) 即可。

[ -r /usr/share/bash-completion/bash_completion ] \
&& . /usr/share/bash-completion/bash_completion

在正常使用 zsh 的命令补全功能之前,我们也需要将下列内容加入到 ~/.zshrc 配置文件中:

# completion
autoload -U compinit
compinit -i

让我们先来看一个自动补全命令选项的例子。我在输入

xiaodong@codeland:~$ find -

后便立即按 Tab,bash 马上列出了可以自动补全的选项列表。如图 2.4 所示。

命令选项自动补全备选列表

图 2.4: 命令选项自动补全备选列表

我接着输入 ina

xiaodong@codeland:~$ find -ina

并再次按下 Tab,此时 bash 自动补全了 -iname 选项。

xiaodong@codeland:~$ find -iname

下面的例子演示了 bash 补全子命令的情形。在输入

xiaodong@codeland:~$ git in

后,按 Tab,bash 提供可以自动补全的子命令列表。

xiaodong@codeland:~$ git in
info       init       instaweb

跟着输入 i

xiaodong@codeland:~$ git ini

并再按 Tab,这次 bash 便自动补全了子命令 init。对于执行 git status 子命令的过程同样如此。

xiaodong@codeland:~$ git init

与 bash 比较而言,zsh 对于命令选项的补全提供更好的用户体验。在下面的例子中,你将看到,zsh 不仅列出了可供补全的选项列表,更有对该选项用途的解释。如图 2.5 所示。此外,正如前面提到的,你还可以选择这些列表项目。

zsh 中的命令选项自动补全

图 2.5: zsh 中的命令选项自动补全

对于子命令的补全,zsh 提供与命令选项补全相同的效果。

此外,子命令以及选项补全也可以合用。在下例中,我先补全了子命令 git status,然后又补全了选项 --verbose

xiaodong@codeland:~$ git sta
stash  -- stash away changes to dirty working directory
status -- show working-tree status
xiaodong@codeland:~$ git status --v
xiaodong@codeland:~$ git status --verbose

2.4.1 Zsh 自动建议插件

对于使用 zsh 的朋友,我在此推荐一个好用的命令自动建议插件。这个插件叫做 zsh-autosuggestions。针对命令进行自动建议这项功能源自于 fish shell,现在,zsh 从其借鉴过来,使得我们这些 zsh 的忠实拥趸也能使用这项好功能。

zsh-autosuggestions 的安装很简单,只需从 GitHub 将其克隆到本机,然后在 .zshrc 中引用 zsh-autosuggestions.zsh 并重新打开终端即可。

xiaodong@codeland:~$ git clone \
https://github.com/zsh-users/zsh-autosuggestions.git \
~/.zsh-autosuggestions
xiaodong@codeland:~$ echo source \
~/.zsh-autosuggestions/zsh-autosuggestions.zsh \
>> ~/.zshrc
xiaodong@codeland:~$ source ~/.zshrc

下面让我们来看看 zsh-autosuggestions 的用法,首先我在没有开启 zsh-autosuggestions 插件的情况下输入 ls -lcd hello_world 等命令,除了能够使用命令补全之外,这儿没有命令的自动建议。当 zsh-autosuggestions 插件开启后,我一旦输入 ls,其后便会出现灰色的自动建议 -la。这是因为 zsh 知道我先前曾输入过 ls -la 这条命令,所以它给出了自动建议。如图 2.6 所示。

zsh 中的命令自动建议

图 2.6: zsh 中的命令自动建议

这时,我们有两种选择:一是按 → (右方向箭) 接受建议,二是继续输入新的内容,这样也就放弃建议了。对于输入 cd h 后,zsh 同样给出了自动建议 ello_world