我正在对我的点文件进行源代码控制,我所做的大部分工作都基于Zach Holman 的点文件。我想像他在文件中所做的那样获取所有 zsh 文件,但在将代码放入其中之前,我想真正了解代码的作用。我感到困惑的代码片段是
# all of our zsh files
typeset -U config_files
config_files=($ZSH/**/*.zsh)
# load the path files
for file in ${(M)config_files:#*/path.zsh}
do
source $file
done
# load everything but the path and completion files
for file in ${${config_files:#*/path.zsh}:#*/completion.zsh}
do
source $file
done
# initialize autocomplete here, otherwise functions won't be loaded
autoload -U compinit
compinit
# load every completion after autocomplete loads
for file in ${(M)config_files:#*/completion.zsh}
do
source $file
done
unset config_files
我最困惑的是这里发生了什么
${(M)config_files:#*/path.zsh}
和这里
${${config_files:#*/path.zsh}:#*/completion.zsh}
那么,这意味着什么?
答案1
PARAMETER EXPANSION
手册页的部分是zshexpn
一个很好的起点。
首先,让我们注意到它是一个包含目录下$config_files
所有文件的数组,正如您在第二行看到的:。.zsh
$ZSH
config_files=($ZSH/**/*.zsh)
该行中使用的语法${(M)config_files:#*/path.zsh}
(请注意,M
括号内的语法称为扩展标志) 如下:
${name:#pattern}
If the pattern matches the value of name, then substitute the
empty string; otherwise, just substitute the value of name.
If name is an array the matching array elements are removed
(use the `(M)' flag to remove the non-matched elements).
换句话说,所讨论的 for 循环遍历path.zsh
$ZSH 中的所有文件。您for file in $ZSH/**/path.zsh
也可以使用,但对文件数组的操作$config_files
比一次又一次递归搜索文件系统更快。(还有更多 for 循环,不是吗?)
有了这些知识,就应该很容易弄清楚该怎么${${config_files:#*/path.zsh}:#*/completion.zsh}
做。(无论如何,结果已在评论中说明)。
我通常会使用一些简单的例子来更好地理解:
$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz
它比看上去的要简单,对吧?!;)