Di zsh, path pencarian fungsi ($ fpath) mendefinisikan satu set direktori, yang berisi file yang dapat ditandai untuk dimuat secara otomatis ketika fungsi yang dikandungnya diperlukan untuk pertama kalinya.
Zsh memiliki dua mode file autoloading: Cara asli Zsh dan mode lain yang menyerupai autoloading ksh. Yang terakhir aktif jika opsi KSH_AUTOLOAD diatur. Mode asli Zsh adalah default dan saya tidak akan membahas cara lain di sini (lihat "man zshmisc" dan "man zshoptions" untuk detail tentang autoloading gaya ksh).
Baik. Katakanlah Anda mendapat direktori `~ / .zfunc 'dan Anda ingin itu menjadi bagian dari jalur pencarian fungsi, Anda melakukan ini:
fpath=( ~/.zfunc "${fpath[@]}" )
Itu menambahkan direktori pribadi Anda ke bagian depan jalur pencarian. Itu penting jika Anda ingin menimpa fungsi dari instalasi zsh dengan milik Anda sendiri (seperti, ketika Anda ingin menggunakan fungsi penyelesaian yang diperbarui seperti `_git 'dari repositori zsh's CVS dengan versi shell yang diinstal lebih lama).
Perlu juga dicatat, bahwa direktori dari `$ fpath 'tidak dicari secara rekursif. Jika Anda ingin direktori pribadi Anda dicari secara rekursif, Anda harus mengurusnya sendiri, seperti ini (cuplikan berikut membutuhkan opsi `EXTENDED_GLOB 'untuk diatur):
fpath=(
~/.zfuncs
~/.zfuncs/**/*~*/(CVS)#(/N)
"${fpath[@]}"
)
Ini mungkin terlihat samar untuk mata yang tidak terlatih, tetapi itu benar-benar hanya menambahkan semua direktori di bawah `~ / .zfunc 'ke` $ fpath', sementara mengabaikan direktori yang disebut "CVS" (yang berguna, jika Anda berencana untuk checkout keseluruhan pohon fungsi dari CVS zsh ke jalur pencarian pribadi Anda).
Mari kita asumsikan Anda punya file `~ / .zfunc / hello 'yang berisi baris berikut:
printf 'Hello world.\n'
Yang perlu Anda lakukan sekarang adalah menandai fungsi yang akan dimuat secara otomatis pada referensi pertamanya:
autoload -Uz hello
"Apa -Uz tentang?", Anda bertanya? Yah, itu hanya satu set opsi yang akan menyebabkan `autoload 'untuk melakukan hal yang benar, tidak peduli opsi apa yang sedang diatur sebaliknya. `U 'menonaktifkan ekspansi alias saat fungsi sedang dimuat dan` z' memaksa gaya-zsh autoloading bahkan jika `KSH_AUTOLOAD 'diatur untuk alasan apa pun.
Setelah itu diatasi, Anda dapat menggunakan fungsi `halo 'baru Anda:
zsh% halo
Halo Dunia.
Sepatah kata tentang sumber file-file ini: Itu hanya salah . Jika Anda akan sumber file `~ / .zfunc / hello ', itu hanya akan mencetak" Hello world. " sekali. Tidak ada lagi. Tidak ada fungsi yang akan ditentukan. Dan selain itu, idenya adalah untuk hanya memuat kode fungsi saat diperlukan . Setelah panggilan `pengisian otomatis ', definisi fungsi tidak dibaca. Fungsi baru saja ditandai untuk diisikan otomatis nanti sesuai kebutuhan.
Dan akhirnya, catatan tentang $ FPATH dan $ fpath: Zsh mempertahankan itu sebagai parameter yang ditautkan. Parameter huruf kecil adalah sebuah array. Versi huruf besar adalah skalar string, yang berisi entri dari array tertaut yang bergabung dengan titik dua di antara entri. Ini dilakukan, karena menangani daftar skalar adalah cara yang lebih alami menggunakan array, sementara juga menjaga kompatibilitas mundur untuk kode yang menggunakan parameter skalar. Jika Anda memilih untuk menggunakan $ FPATH (skalar), Anda harus berhati-hati:
FPATH=~/.zfunc:$FPATH
akan berfungsi, sementara yang berikut tidak akan:
FPATH="~/.zfunc:$FPATH"
Alasannya adalah bahwa ekspansi tilde tidak dilakukan dalam tanda kutip ganda. Ini kemungkinan sumber masalah Anda. Jika echo $FPATH
mencetak tilde dan bukan jalur yang diperluas maka itu tidak akan berfungsi. Agar aman, saya akan menggunakan $ HOME alih-alih tilde seperti ini:
FPATH="$HOME/.zfunc:$FPATH"
Yang sedang berkata, saya lebih suka menggunakan parameter array seperti yang saya lakukan di bagian atas penjelasan ini.
Anda juga tidak boleh mengekspor parameter $ FPATH. Ini hanya dibutuhkan oleh proses shell saat ini dan bukan oleh anak-anaknya.
Memperbarui
Mengenai isi file dalam `$ fpath ':
Dengan gaya-otomatis zsh, konten file adalah isi dari fungsi yang ditentukannya. Dengan demikian file bernama "halo" yang mengandung garis echo "Hello world."
sepenuhnya mendefinisikan fungsi yang disebut "halo". Anda bebas untuk memasukkan
hello () { ... }
kode, tetapi itu akan berlebihan.
Klaim bahwa satu file hanya boleh berisi satu fungsi tidak sepenuhnya benar.
Terutama jika Anda melihat beberapa fungsi dari fungsi sistem penyelesaian berbasis (compsys) Anda akan segera menyadari bahwa itu adalah kesalahpahaman. Anda bebas menentukan fungsi tambahan dalam file fungsi. Anda juga bebas melakukan inisialisasi apa pun, yang mungkin perlu Anda lakukan saat fungsi pertama kali dipanggil. Namun, ketika Anda melakukannya, Anda akan selalu mendefinisikan fungsi yang dinamai seperti file dalam file dan memanggil fungsi itu di akhir file, sehingga dijalankan saat pertama kali fungsi direferensikan.
Jika - dengan sub-fungsi - Anda tidak mendefinisikan fungsi yang dinamai seperti file di dalam file, Anda akan berakhir dengan fungsi yang memiliki definisi fungsi di dalamnya (yaitu sub-fungsi dalam file). Anda secara efektif akan mendefinisikan semua sub-fungsi Anda setiap kali Anda memanggil fungsi yang dinamai seperti file. Biasanya, itu bukan yang Anda inginkan, jadi Anda akan mendefinisikan ulang suatu fungsi, yang dinamai seperti file di dalam file.
Saya akan menyertakan kerangka pendek, yang akan memberi Anda gambaran tentang cara kerjanya:
# Let's again assume that these are the contents of a file called "hello".
# You may run arbitrary code in here, that will run the first time the
# function is referenced. Commonly, that is initialisation code. For example
# the `_tmux' completion function does exactly that.
echo initialising...
# You may also define additional functions in here. Note, that these
# functions are visible in global scope, so it is paramount to take
# care when you're naming these so you do not shadow existing commands or
# redefine existing functions.
hello_helper_one () {
printf 'Hello'
}
hello_helper_two () {
printf 'world.'
}
# Now you should redefine the "hello" function (which currently contains
# all the code from the file) to something that covers its actual
# functionality. After that, the two helper functions along with the core
# function will be defined and visible in global scope.
hello () {
printf '%s %s\n' "$(hello_helper_one)" "$(hello_helper_two)"
}
# Finally run the redefined function with the same arguments as the current
# run. If this is left out, the functionality implemented by the newly
# defined "hello" function is not executed upon its first call. So:
hello "$@"
Jika Anda menjalankan contoh konyol ini, proses pertama akan terlihat seperti ini:
zsh% halo
menginisialisasi ...
Halo Dunia.
Dan panggilan berurutan akan terlihat seperti ini:
zsh% halo
Halo Dunia.
Saya harap ini jelas.
(Salah satu contoh dunia nyata yang lebih kompleks yang menggunakan semua trik itu adalah fungsi ` _tmux 'yang telah disebutkan dari sistem penyelesaian berbasis fungsi zsh.)