GNU/Linux >> Belajar Linux >  >> Ubuntu

Ubuntu – Bagaimana Cara Membuat Penyelesaian Zsh Kustom “hanya Bekerja” dengan Benar?

Maafkan saya jika saya melakukan sesuatu yang bodoh di sini, dokumentasinya sangat besar dan pencarian belum menghasilkan apa-apa.

Saya mencoba membuat penyelesaian shell untuk skrip khusus saya yang disebut fab . Untuk bash itu mudah, cukup taruh di /etc/bash_completion.d dan mereka bekerja. Tapi astaga, apakah zsh adalah PITA…

Saya memiliki fungsi penyelesaian _fab dan berfungsi dengan baik saat diaktifkan dengan compdef _fab fab . Saya memasukkannya ke /usr/share/zsh/vendor-completions/_fab yang sudah ada di $fpath saya . File dimulai dengan #compdef fab dan diakhiri dengan compdef _fab fab . Terlihat bagus:

$ type _fab
_fab is an autoload shell function

Tetapi setiap kali saya memulai shell baru, fab penyelesaian tidak berfungsi (fungsi lain dari vendor-completions , seperti _docker , kami baik-baik saja). compinit memperbaiki ini untuk shell khusus itu. Saya menemukan bahwa rm ~/.zcompdump ~/.zcompdump-$(hostname)-5.1.1; compinit membuatnya bekerja secara permanen (5.1.1 =versi zsh saya).

Pertanyaan:

  1. Apa dan kapan membaca ~/.zcompdump untuk menyiapkan penyelesaian awal?
  2. man zshall mengatakan:

    Pemanggilan compinit berikutnya akan membaca file yang dibuang alih-alih melakukan inisialisasi penuh.

    Jika itu masalahnya, compinit tidak akan memperbaiki penyelesaian saya sebelum saya menghapus ~/.zcompdump , Baik? Apakah saya melewatkan sesuatu?

  3. Apa itu ~/.zcompdump-$(hostname)-5.1.1 dan bagaimana hubungannya dengan .zcompdump ? Satu-satunya perbedaan adalah satu penyelesaian yang ada di ~/.oh-my-zsh/completions (karena $ZSH menunjuk ke ~/.oh-my-zsh ). Apakah ini hal yang aneh?
  4. Jika saya mengemas penyelesaian ini ke dalam paket yang dapat didistribusikan ulang atau membuat skrip penginstal, di mana saya harus meletakkan penyelesaian zsh dan apa lagi yang harus saya lakukan selama penginstalan untuk memastikan semuanya berfungsi?

Saya menargetkan Ubuntu 16.04, 18.04 dan 19.04, tetapi informasi khusus non-distro diterima. Saya menguji ini di Ubuntu 16.04 dengan zsh 5.1.1 dan terbaru oh-my-zsh.

Jawaban yang Diterima:

TL,DR:Dalam operasi normal, cukup letakkan file ke direktori yang sesuai. Saat menguji, Anda perlu menghapus file cache (.zcompdump secara default, tetapi pengguna dapat meletakkannya di lokasi yang berbeda, dan oh-my-zsh meletakkannya di lokasi yang berbeda).

Jawaban sederhananya adalah menulis fungsi penyelesaian dalam file di mana baris pertama adalah #compdef fab . File harus berada dalam direktori di $fpath .

File dapat berisi badan fungsi, atau definisi fungsi yang diikuti dengan panggilan ke fungsi tersebut. Artinya, file tersebut berisi sesuatu seperti

#compdef fab
_arguments …

atau

#compdef fab
function _fab {
  _arguments …
}
_fab "[email protected]"

File harus ada di $fpath sebelum compinit berjalan. Itu berarti Anda perlu memperhatikan urutan hal-hal di .zshrc :pertama tambahkan direktori khusus apa pun ke $fpath , lalu panggil compinit . Jika Anda menggunakan kerangka kerja seperti oh-my-zsh, pastikan untuk menambahkan direktori khusus apa pun ke $fpath sebelum kode oh-my-zsh.

compinit adalah fungsi yang menginisialisasi sistem penyelesaian. Ia membaca semua file di $fpath dan memeriksa baris pertama mereka untuk arahan ajaib #autoload dan #compdef .

.zcompdump adalah file cache yang digunakan oleh compinit . ~/.zcompdump adalah lokasi default; Anda dapat memilih lokasi yang berbeda saat menjalankan compinit . Astaga, panggilan compinit dengan -d opsi untuk menggunakan nama file cache yang berbeda yang diberikan oleh variabel ZSH_COMPDUMP , yang defaultnya adalah

ZSH_COMPDUMP="${ZDOTDIR:-${HOME}}/.zcompdump-${SHORT_HOST}-${ZSH_VERSION}"

Nama host disertakan untuk kepentingan orang-orang yang direktori home-nya dibagi antara mesin dan yang mungkin memiliki perangkat lunak berbeda yang diinstal pada mesin yang berbeda. Versi zsh disertakan karena file cache tidak kompatibel antar versi (termasuk kode yang berubah dari versi ke versi).

Terkait:Apa yang dilakukan CTRL+V di vim?

Saya pikir semua masalah Anda disebabkan oleh file cache yang basi (dan itu membuat Anda terlalu memperumit situasi). Sayangnya, algoritma zsh untuk menentukan apakah file cache basi tidak sempurna, mungkin demi kecepatan. Itu tidak memeriksa konten atau stempel waktu file di $fpath , itu hanya menghitung mereka. Sebuah .zcompdump file dimulai dengan baris seperti

#files: 858     version: 5.1.1

Jika versi zsh dan jumlah file sudah benar, zsh akan memuat file cache.

File cache hanya berisi asosiasi antara nama perintah, bukan kode fungsi penyelesaian. Berikut adalah beberapa skenario umum di mana cache bekerja secara transparan:

  • Jika Anda menambahkan file baru ke $fpath , ini membuat cache menjadi tidak valid.
  • Lebih umum lagi, jika Anda menambahkan dan menghapus file di $fpath , dan jumlah total file yang dihapus tidak sama dengan jumlah total file yang dihapus, ini membuat cache menjadi tidak valid.
  • Jika Anda memindahkan file ke direktori lain di $fpath tanpa mengubah namanya, ini tidak mempengaruhi apa pun yang ada di cache, jadi cache tetap benar.
  • Jika Anda memodifikasi file di $fpath tanpa mengubah baris pertama, ini tidak mempengaruhi apa pun yang ada di cache, jadi cache tetap benar.

Berikut adalah beberapa skenario umum di mana cache menjadi tidak valid, tetapi zsh tidak menyadarinya.

  • Anda menambahkan beberapa file ke $fpath dan hapus jumlah file yang sama persis.
  • Anda mengganti nama file di $fpath .
  • Anda menambah atau mengubah #compdef (atau #autoload ) baris di bagian atas file.

Poin terakhir itulah yang cenderung menggigit selama pengujian. Jika Anda mengubah #compdef baris, Anda harus menghapus .zcompdump file dan mulai ulang zsh (atau jalankan kembali compinit ).

Jika Anda memasukkan penyelesaian dalam paket yang dapat didistribusikan ulang, cukup letakkan file penyelesaian ke dalam direktori yang ada di $fpath seluruh sistem . Untuk paket Ubuntu, tempat yang sesuai adalah /usr/share/zsh/vendor-completions . Untuk sesuatu yang diinstal di bawah /usr/local , itu /usr/local/share/zsh/site-functions . Hanya itu yang perlu Anda lakukan.

Satu hal yang tidak transparan adalah jika Anda perlu mengubah #compdef baris dalam peningkatan, atau jika Anda menghapus atau mengganti nama beberapa file. Dalam kasus seperti itu, pengguna harus menghapus file cache mereka, dan itu bukan sesuatu yang dapat Anda lakukan dari paket yang diinstal pada mesin multipengguna.


Ubuntu
  1. Cara Menginstal Oh My Zsh di Ubuntu

  2. Bagaimana Cara Menginstal Zsh di Ubuntu 20.04?

  3. Cara Menginstal Nagios di Ubuntu 14.04

  1. Cara Menambahkan File Swap Di Ubuntu

  2. Bagaimana Cara Membuat Animasi Splash Boot-up Kustom?

  3. Cara Menginstal ZSH di Ubuntu 20.04

  1. Cara Mengubah Nama Host di Ubuntu 18.04

  2. Cara menghapus file di Ubuntu Linux

  3. Cara menginstal g ++ di Ubuntu