zsh นี้สำหรับไวยากรณ์หมายความว่าอย่างไร


4

ผมทำงานเกี่ยวกับแหล่งที่มาของการควบคุมและ dotfiles LOF ของสิ่งที่ฉันทำของฉันจะตามออกdotfiles ซัคฮอลของ ฉันต้องการแหล่งที่มาของไฟล์ 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}

ดังนั้นสิ่งนี้หมายความว่าอย่างไร

คำตอบ:


4

PARAMETER EXPANSIONส่วนของzshexpnหน้าคนเป็นจุดเริ่มต้นที่ดี

ครั้งแรกที่ช่วยให้ทราบว่า$config_filesเป็นอาร์เรย์รวมทั้ง.zshไฟล์ภายใต้ไดเรกทอรีที่คุณสามารถเห็นในบรรทัดที่สอง:$ZSHconfig_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).

กล่าวอีกนัยหนึ่งการวนซ้ำที่มีปัญหาจะวนซ้ำทุกpath.zshไฟล์ใน $ ZSH คุณสามารถใช้for file in $ZSH/**/path.zshเช่นกัน แต่การดำเนินการบน$config_filesอาเรย์ไฟล์นั้นเร็วกว่าการค้นหาระบบไฟล์ซ้ำ ๆ ซ้ำ ๆ (มีลูปอีกมากใช่ไหม)

ด้วยความรู้ที่ว่ามันควรจะง่ายต่อการคิดออกว่า${${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

ง่ายกว่าที่คิดใช่มั้ย! ;)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.