Estou trabalhando no controle de origem dos meus dotfiles e muito do que estou fazendo é baseado emArquivos de pontos de Zach Holman. Quero obter todos os arquivos zsh como ele faz em seus arquivos, mas antes de colocar o código lá, quero realmente entender o que o código está fazendo. O trecho com o qual estou confuso é
# 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
Principalmente estou confuso sobre o que está acontecendo aqui
${(M)config_files:#*/path.zsh}
e aqui
${${config_files:#*/path.zsh}:#*/completion.zsh}
Então, o que tudo isso significa?
Responder1
A PARAMETER EXPANSION
seção da zshexpn
página de manual é um bom ponto de partida.
Primeiro, observemos que $config_files
é um array que inclui todos .zsh
os arquivos do $ZSH
diretório, como você pode ver na segunda linha: config_files=($ZSH/**/*.zsh)
.
Esta sintaxe usada na linha ${(M)config_files:#*/path.zsh}
(observe que M
entre parênteses é chamada debandeira de expansão) é o seguinte:
${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).
Em outras palavras, o loop for em questão itera sobre todos path.zsh
os arquivos em $ZSH. Você for file in $ZSH/**/path.zsh
também poderia usar, mas a operação na $config_files
matriz de arquivos é mais rápida do que pesquisar recursivamente no sistema de arquivos repetidas vezes. (Há mais loop for, não há?)
Com esse conhecimento, deve ser fácil descobrir o que ${${config_files:#*/path.zsh}:#*/completion.zsh}
acontecerá. (O resultado é indicado no comentário de qualquer maneira).
Normalmente uso alguns exemplos triviais para me entender melhor:
$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz
É mais fácil do que parece, né?!;)