Ich arbeite an der Quellcodeverwaltung meiner Dotfiles und vieles von dem, was ich mache, basiert aufZach Holmans Dotfiles. Ich möchte alle zsh-Dateien als Quelle verwenden, so wie er es in seinen Dateien tut, aber bevor ich den Code einfach dort hineinwerfe, möchte ich wirklich verstehen, was der Code macht. Der Codeausschnitt, der mich verwirrt, ist
# 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
Vor allem bin ich verwirrt, was hier passiert
${(M)config_files:#*/path.zsh}
und hier
${${config_files:#*/path.zsh}:#*/completion.zsh}
Was bedeutet das alles?
Antwort1
Der PARAMETER EXPANSION
Abschnitt der zshexpn
Manpage ist ein guter Ausgangspunkt.
Beachten Sie zunächst, dass $config_files
es sich um ein Array handelt, das alle .zsh
Dateien im $ZSH
Verzeichnis enthält, wie Sie in der zweiten Zeile sehen können: config_files=($ZSH/**/*.zsh)
.
Diese in der Zeile verwendete Syntax ${(M)config_files:#*/path.zsh}
(bitte beachten Sie, dass M
innerhalb der Klammern einErweiterungsflagge) ist das Folgende:
${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).
Mit anderen Worten, die betreffende For-Schleife durchläuft alle path.zsh
Dateien in $ZSH. Sie könnten for file in $ZSH/**/path.zsh
auch verwenden, aber die Operation auf dem $config_files
Dateiarray ist schneller, als das Dateisystem immer wieder rekursiv zu durchsuchen. (Es gibt noch mehr For-Schleifen, oder nicht?)
Mit diesem Wissen sollte es einfach sein, herauszufinden, was ${${config_files:#*/path.zsh}:#*/completion.zsh}
passieren wird. (Das Ergebnis wird ohnehin im Kommentar angegeben.)
Ich verwende normalerweise einige triviale Beispiele, um selbst ein besseres Verständnis zu bekommen:
$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz
Es ist einfacher, als es aussieht, oder?!;)