更好地理解“zsh”中扩展别名的函数

use*_*381 4 zsh

我试图了解这个zsh小部件的工作原理:

\n\n
expand-aliases() {\n  unset \'functions[_expand-aliases]\'\n  functions[_expand-aliases]=$BUFFER\n  (($+functions[_expand-aliases])) &&\n    BUFFER=${functions[_expand-aliases]#$\'\\t\'} &&\n    CURSOR=$#BUFFER\n}\n\nzle -N expand-aliases\nbindkey \'\\e^E\' expand-aliases\n
Run Code Online (Sandbox Code Playgroud)\n\n

我在这个答案中找到了代码。它的目的是当您点击 时展开命令行上的所有别名C-M-e

\n\n

它有效,但代码中有几件事我不明白。

\n\n

这是我认为我理解的和我不理解的:

\n\n
zle -N expand-aliases\n
Run Code Online (Sandbox Code Playgroud)\n\n

此行安装一个名为的小部件expand-aliases,它将调用具有相同名称的函数。

\n\n
bindkey \'\\e^E\' expand-aliases\n
Run Code Online (Sandbox Code Playgroud)\n\n

该行将小部件绑定到关键和弦C-M-e

\n\n
unset \'functions[_expand-aliases]\'\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不明白这一行,因为我不知道数组functions是如何填充的。

\n\n
functions[_expand-aliases]=$BUFFER\n
Run Code Online (Sandbox Code Playgroud)\n\n

该行将当前命令行的内容存储在关联数组内functions,键为_expand-aliases

\n\n
(($+functions[_expand-aliases])) &&\n
Run Code Online (Sandbox Code Playgroud)\n\n

为了更好地理解该行的工作原理,我执行了以下命令:

\n\n
alias ls=\'ls --color=auto\'\nalias -g V=\'|vipe\'\nfunctions[_expand-aliases]=\'ls V\'\necho $functions[_expand-aliases]           \xe2\x86\x92  ls --color=auto | vipe\necho $+functions[_expand-aliases]          \xe2\x86\x92  1\n(($+functions[_expand-aliases])); echo $?  \xe2\x86\x92  0\n
Run Code Online (Sandbox Code Playgroud)\n\n

我不确定,但从这些结果来看,我认为$functions[_expand-aliases]以某种方式扩展了当前命令行中的别名,并$+functions[_expand-aliases]返回一个布尔标志,用于检查命令行在语法上是否有效。

\n\n

但是,我不明白该$+令牌。我在所有的搜索中都找到了它zsh,但找不到它。

\n\n
BUFFER=${functions[_expand-aliases]#$\'\\t\'} &&\n
Run Code Online (Sandbox Code Playgroud)\n\n

该行可能重新定义了命令行的内容及其扩展。

\n\n
CURSOR=$#BUFFER\n
Run Code Online (Sandbox Code Playgroud)\n\n

该行将光标定位在命令的末尾。

\n\n
\n\n

有人可以更好地解释这段代码是如何工作的吗?或者至少引用zsh手册页中描述$+令牌和functions数组的部分?

\n

Gil*_*il' 6

$+functions[_expand-aliases]如果关联数组functions包含键,则为 1 _expand-aliases,否则为 0。这在手册中描述为。在 的条目下,手册解释说大括号是可选的。我不认为手册明确指出您可以使用带有下标的数组名称而不是名称。zsh 手册并不容易阅读。${+name}${name}

\n\n

functions数组是一个与函数定义相关的 \xe2\x80\x9cmagic\xe2\x80\x9d 关联数组。定义函数会向该数组添加一个元素,其中键是函数名称,值是规范化的函数体。相反,向数组添加元素会定义具有给定名称和主体的函数。

\n\n
unset \'functions[_expand-aliases]\'               # unset any previous function\nfunctions[_expand-aliases]=$BUFFER               # define a function whose body is the content of the command line\n(($+functions[_expand-aliases])) &&              # if the command line is a syntactically correct function body, then \xe2\x80\xa6\nBUFFER=${functions[_expand-aliases]#$\'\\t\'} &&    # set the command line to the normalized function definition\nCURSOR=$#BUFFER                                  # move the cursor to the end of the command line\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果functions是一个普通数组,那么这不会改变 的值BUFFER(除了去掉前导制表符),并且第三行的测试将始终为真。但由于 \xe2\x80\x9cmagic\xe2\x80\x9d 的性质functions,你从中得到的并不是你放入的,它是一个规范化版本 \xe2\x80\x94\xc2\xa0 特别是,别名已扩展。如果函数定义在语法上不正确,则第三行的测试将失败。

\n