Co oznacza ta Zsh dla składni?

4

Pracuję nad źródłem kontrolującym moje pliki kropkowe, a część tego, co robię, oparta jest na plikach kropkowych Zacha Holmana . Chcę źródła wszystkich plików ZH, tak jak on, w swoich plikach, ale zanim po prostu wrzucę tam kod, chcę naprawdę zrozumieć, co robi kod. Fragment, który mnie myli, to

# 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

Głównie jestem zdezorientowany, co się tutaj dzieje

${(M)config_files:#*/path.zsh}

i tu

${${config_files:#*/path.zsh}:#*/completion.zsh}

Co to wszystko znaczy?

Rumel
źródło

Odpowiedzi:

4

PARAMETER EXPANSIONOdcinek zshexpnmanualu jest dobrym punktem wyjścia.

Po pierwsze, pozwala zauważyć, że $config_filesjest tablicą w tym wszystkich .zshplików w $ZSHkatalogu, jak widać w drugim wierszu: config_files=($ZSH/**/*.zsh).

Ta składnia zastosowana w wierszu ${(M)config_files:#*/path.zsh}(zwróć uwagę, że Mw nawiasach nazywa się flagą rozwijania ) jest następująca:

${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).

Innymi słowy, path.zshomawiana pętla for iteruje wszystkie pliki w $ ZSH. Możesz także użyć for file in $ZSH/**/path.zsh, ale operacja na $config_filestablicy plików jest szybsza niż rekurencyjne przeszukiwanie systemu plików. (Jest więcej dla pętli, prawda?)

Dzięki tej wiedzy powinno być łatwo ustalić, co się ${${config_files:#*/path.zsh}:#*/completion.zsh}stanie. (Wynik jest podany w komentarzu i tak).


Zwykle używam kilku trywialnych przykładów, aby lepiej zrozumieć siebie:

$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz

To łatwiejsze niż się wydaje, prawda ?! ;)

mpy
źródło