Dapatkah skrip penyelesaian tab Bash digunakan di zsh?

87

Saya memiliki skrip penyelesaian tab Bash untuk Apache's Hadoop. Biasanya, saya menggunakan zsh sebagai shell sehari-hari. Ini cenderung seperti pesta ketika saya membutuhkannya, tetapi sepertinya sistem penyelesaian tab sangat berbeda di antara mereka. Apakah ada cara sederhana untuk "mengubah" definisi penyelesaian-tab-bash yang ada agar berfungsi di zsh? Saya tidak ingin menginvestasikan banyak waktu dalam hal ini, tetapi jika itu mudah, saya akan menghemat sedikit usaha.

Pembuat kode
sumber

Jawaban:

39

Dari halaman ini (tertanggal 2010/01/05):

Zsh dapat menangani fungsi penyelesaian bash. Versi pengembangan terbaru dari zsh memiliki fungsi bashcompinit, yang ketika dijalankan akan memungkinkan zsh untuk membaca spesifikasi dan fungsi penyelesaian bash. Ini didokumentasikan di halaman manual zshcompsys. Untuk menggunakannya, yang perlu Anda lakukan hanyalah menjalankan bashcompinit kapan saja setelah compinit. Ini akan menentukan fungsi lengkap dan compgen yang sesuai dengan bash bawaan.

Dennis Williamson
sumber
Kabar baiknya: Saya pikir ini seharusnya berhasil, jadi terima kasih banyak. Kabar buruknya: untuk beberapa alasan, sistem tempat saya mencoba melakukan ini tampaknya tidak memuat / etc / zshrc ketika saya masuk melalui SSH. Saya tidak cukup tahu tentang proses login untuk mengetahui mengapa ini terjadi. Mungkin waktu untuk mengajukan pertanyaan lain ...
Coderer
1
@Coderer: Pertama-tama, Anda mengucapkan "/ etc / zshrc". Di sistem saya, ini /etc/zsh/zshrc. Juga, periksa file-file berikut dalam urutan terbalik (tercantum dalam urutan mereka bersumber pada startup zsh): /etc/zsh/zshenv, $ZDOTDIR/.zshenv, /etc/zsh/zprofiledan $ZDOTDIR/.zprofile(mungkin ~/.zprofile) untuk melihat apakah RCSvariabel diset. Jika ya, itu akan mencegah file berikutnya setelah file yang tidak disetel untuk bersumber. Terakhir, periksa shell untuk pengguna masuk /etc/passwddan pastikan itu zshdan pastikan tidak ada -fargumen.
Dennis Williamson
Terima kasih atas semua umpan baliknya - Saya menggunakan peretasan programmer klasik # 1, "stdout debugging" (pernyataan gema di setiap skrip startup) dan menemukan masalahnya. Untuk beberapa alasan, / etc / zprofile kami mengambil berbagai skrip /etc/profile.d, yang kemudian diambil kembali di / etc / zshrc. Cukup memindahkan pernyataan muat otomatis ke bagian atas / etc / zprofile telah memperbaiki masalah.
Coderer
158
autoload bashcompinit
bashcompinit
source /path/to/your/bash_completion_file
freestyler
sumber
10
Ini adalah jawaban yang lebih baik karena memberi tahu Anda cara menggunakan bashcompinit. Pekerjaan yang baik.
pyrospade
5
Terima kasih, jawaban yang bagus, sayangnya ini tidak berfungsi jika skrip menggunakan perintah _init_completion bash.
0fnt
6
Ini tidak berhasil untuk saya. Saya masih mendapatkan complete:13: command not found: compdefkesalahan.
Jatin Kumar
Jika tidak berhasil, periksa skrip (doh :)) - mungkin ada if is-bashcentang di bagian atas.
olejorgenb
Ini tidak berfungsi untuk beberapa skrip yang menggunakan _get_comp_words_by_refyang tidak ditentukan oleh bashcompinit. Kebanyakan penyelesaian tidak menggunakan fungsi ini.
Franklin Yu
41
autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit
source /path/to/your/bash_completion_script

Saya menjalankan zsh zsh 5.0.2 (x86_64-apple-darwin13.0) tanpa ~ / .zshrc dan urutan di atas bekerja di shell zsh yang baru saja muncul.

Terima kasih kepada skrip git-complete.bash untuk petunjuknya: D


Baca terus untuk detail lebih lanjut tentang 3 baris di atas:

Bash memiliki mengagumkan di dibangun dukungan penyelesaian otomatis tetapi script bash autocomplete tidak bekerja secara langsung zsh sebagai lingkungan zsh tidak memiliki autocomplete pesta penting fungsi pembantu suka compgen, complete. Itu dilakukan dalam upaya untuk menjaga sesi zsh cepat.

Saat ini zsh dikirimkan dengan skrip penyelesaian yang sesuai seperti compinitdan bashcompinityang memiliki fungsi yang diperlukan untuk mendukung skrip pelengkapan otomatis bash.

autoload <func_name>: Perhatikan bahwa muat otomatis didefinisikan dalam zsh dan bukan bash. autoloadmencari file bernama di jalur direktori yang dikembalikan oleh fpathperintah dan menandai fungsi untuk memuat yang sama saat pertama kali dipanggil.

  • -U: Abaikan alias apa pun saat memuat fungsi seperti compinit atau bashcompinit
  • + X: Cukup muat fow fungsi bernama sekarang dan jangan jalankan

Misalnya pada echo $fpathpengembalian sistem saya /usr/share/zsh/site-functionsdan /usr/share/zsh/5.0.5/functionsdan keduanya compinitdan bashcompinittersedia di /usr/share/zsh/5.0.5/functions.

Juga bagi kebanyakan orang mungkin hanya autoload -U +X bashcompinit && bashcompinitdiperlukan karena beberapa skrip lain seperti git autocomplete atau milik mereka sendiri ~/.zshrcmungkin dilakukan autoload -U +X compinit && compinit, tetapi aman untuk menjalankan keduanya saja.

Jatin Kumar
sumber
Untuk apa -Udan +Xuntuk apa?
jmk
Jawaban yang diperbarui dengan detail lebih lanjut.
Jatin Kumar
6
Ini masih sedikit masuk akal; manpage mendeskripsikan pentingnya +X foomelakukan pemuatan otomatis yang sama seperti pemanggilan foo, tetapi tanpa segera mengeksekusinya… jadi autoload +X foo && footampaknya sangat berlebihan. Bisakah Anda menjelaskan mengapa Anda memilih pola ini?
ELLIOTTCABLE
2
@ELLIOTTCABLE Maksud dari melakukan autoload -U +X bashcompinit && bashcompinitadalah (karena &&) itu akan mengeksekusi bashcompinitIFF modul benar-benar ditemukan. Normal autoload fooselalu mengembalikan nilai true. Nanti, ketika Anda mencoba untuk menjalankan foo, maka zsh akhirnya memberitahu Anda "file definisi fungsi tidak ditemukan". Dengan autoload +XAnda segera dapatkan kesalahan.
FeRD
1
Halaman manual masih agak tidak jelas tentang hal itu, menurut saya: autoload +Xmemuat fungsi tanpa menjalankannya - yang lebih dari yang autoloaddilakukan, tanpa +X. Tanpa +X, muat otomatis bahkan tidak memuat fungsi; Ini hanya menandai nama sebagai referensi fungsi yang akan dimuat nanti. Pemuatan sebenarnya tidak dilakukan hingga fungsi tersebut dipanggil pertama kali. Jika Anda ingin menentukan apakah fungsi bernama berhasil dimuat, Anda perlu menggunakan +Xuntuk melakukan langkah pemuatan segera.
FeRD
4

Untuk zshdigunakan:

  • compdef
  • compadd

Contoh saya:

# bash completion for bxrun (/home/ecuomo/projects/bashx/bxrun)
_bxrun_methods() {
    grep "^\s*\(function\s\+\)\?__.\+()\s*{.*$" "${1}" | while read line ; do
        echo "$line" | sed "s/()\s*{.*//g" | sed "s/\s*\(function\s\+\)\?__//g"
    done
}
_bxrun_lst() {
    if [ -d "/home/ecuomo/projects/bashx/src/actions" ]; then
        for f in /home/ecuomo/projects/bashx/src/actions/* ; do
            if [ -f "${f}" ]; then
                basename "${f}" | sed 's/\..*$//g'
            fi
        done
    fi
    _bxrun_methods "/home/ecuomo/projects/bashx/bxrun"
    _bxrun_methods "/home/ecuomo/projects/bashx/src/bashx.sh"
}
_bxrun() {
    local cur
    COMPREPLY=()
    cur=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=( $( compgen -W '$( _bxrun_lst )' -- $cur  ) )
}
_bxrun_zsh() {
    compadd `_bxrun_lst`
}
if type complete >/dev/null 2>/dev/null; then
    # bash
    complete -F _bxrun bxrun
else if type compdef >/dev/null 2>/dev/null; then
    # zsh
    compdef _bxrun_zsh bxrun
fi; fi

Sumber: Kode saya https://github.com/reduardo7/bashx

Eduardo Cuomo
sumber
1
Anda harus mengungkapkan bahwa Anda adalah penulis framework bashx tertaut.
Ben
4

Saya menjalankan Antigen sebagai pengelola plugin Oh-My-Zsh. Saya memiliki beberapa skrip penyelesaian bash yang ditulis oleh rekan kerja yang ingin saya muat ke Zsh dengan sederhana source /path/to/completion.

Saya mengalami beberapa masalah, karena sepertinya Antigen atau OMZ (sulit untuk dikatakan) menyangkut diri mereka sendiri dengan hanya memuat skrip penyelesaian dari plugin mereka. Saya akhirnya menyiasati ini dengan pemuatan otomatis bashcompinit dan compinit setelahnya antigen apply. Pemuatan otomatis bashcompinitsaja tidak cukup.

source ~/.antigen/antigen.zsh
antigen use oh-my-zsh
antigen apply

autoload -U +X compinit && compinit
autoload -U +X bashcompinit && bashcompinit

source /path/to/bash_completion

Antigen membuat .zcompdumpfile $ANTIGEN_COMPDUMPyang bagi saya adalah~/.antigen/.zcompdump

Memanggil ulang compinit dan bashcompinit membuat .zcompdump kedua di $HOME/.zcompdump

Yang tampaknya untuk semua pekerjaan keluar, karena saya dapat menggunakan penyelesaian yang didirikan oleh /path/to/bash_completion. Saya telah menghapus kedua file .zcompdump beberapa kali untuk memastikan mereka dibuat ulang dan tampaknya berfungsi.

Saya harus meng-rm file .zcompdump beberapa kali setelah reboot mesin karena kesalahan terjadi saat mencoba menyelesaikan tab, tetapi saya tidak yakin apakah itu karena pengaturan ini atau sesuatu yang lain. rm ~/.zcompdump && rm $ANTIGEN_COMPDUMPdan shell baru memperbaikinya untuk saya.

Versi yang digunakan pada saat penulisan:

Antigen = v2.2.3 = d3d4ee0
Oh-my-zsh = c3b072e
Zsh = 5.3
Walter Wilfinger
sumber
0

Jawaban @ JatinKumar membuat saya di jalur yang benar, tetapi saya harus menggunakan completesebagai gantinya source. Jadi semuanya:

autoload -Uz compinit && compinit
autoload -U +X bashcompinit && bashcompinit

complete -C /usr/local/bin/terraform terraform
complete -C /usr/local/aws/bin/aws_completer aws
complete -C /usr/local/bin/az az
jschmitter
sumber