Idealnya, saya ingin dapat menyimpan seluruh isi .emacs.d
direktori saya dan memilikinya "hanya berfungsi" pada Emacs mana pun saya memuatnya, tetapi masih memanfaatkan setiap fitur dari lingkungan spesifik, seperti sistem windowing GUI.
Saya tidak mencari ensiklopedia fitur yang tidak kompatibel. Saya hanya ingin tahu cara memeriksa fitur, OS, versi, grafik, dll, dan cara memanfaatkannya tanpa melanggar kode untuk konfigurasi lain.
Apa teknik dasar yang dapat saya gunakan untuk menulis Elisp yang bekerja di beberapa versi Emacs yang umum di alam liar (mis. 22.x +) dan pada beberapa platform yang mendasarinya (misalnya OSX, Linux, Windows, dan * nix lainnya), sambil mengambil keuntungan dari platform dan fitur khusus versi mana yang berlaku?
sumber
window-system
, dll dapat dijawab secara wajar di sini.forward-char
dan Anda ingin pertanyaan itu diubah untuk ditanyakanscroll-up
? Jika OP menginginkan kompatibilitas Emacs 22+, biarkan saja. Dan tidak, pertanyaan yang diajukan bukan hanya tentang OS X. Dan ya, masih banyak orang yang menggunakan versi Emacs yang lebih lama (beberapa bahkan lebih tua dari 22, FWIW).Jawaban:
Elisp adalah bahasa yang ditafsirkan. Anda dapat memasukkan kode khusus versi ke dalam kode Anda
.emacs
, tetapi melindunginya dengan menguji pada waktu buka yang beroperasi pada versi yang benar.Kode ini akan berfungsi di semua versi karena
(shiny-new-feature)
hanya dievaluasi ketika(is-new-feature-available)
mengembalikan true. Sebagian besar jawaban ini ditujukan untuk bagaimana menerapkan(is-new-feature-available)
.Mengatasi berbagai set fitur
Lebih baik menguji apakah fitur tersedia daripada menguji versi Emacs. Terkadang fitur tersebut tersedia sebagai paket opsional. Jika Anda ingin menjalankan kode dalam XEmacs atau varian Emacs lainnya, mungkin ia memperoleh fitur yang sama di versi yang berbeda. Gunakan fungsi
boundp
untuk menguji apakah suatu variabel tersedia, danfboundp
untuk menguji apakah suatu fungsi tersedia.Misalnya, cuplikan berikut ini mengikat kunci untuk beralih
visual-line-mode
jika tersedia, danlonglines-mode
sebaliknya.Terkadang, daripada menguji fitur, lebih mudah untuk menjalankan sepotong kode kecil dan mengabaikan kesalahan apa pun karena fungsi yang tidak terdefinisi, argumen yang tidak valid, dll. Jangan lakukan ini untuk sejumlah besar kode, karena ini akan membuat kode Anda sangat sulit di-debug.
Misalnya, saya tidak ingin melihat bilah alat. Versi Emacs yang lebih lama tidak memilikinya sama sekali. GNU Emacs dan XEmacs menambahkan fitur itu dengan cara yang berbeda dan menjadikannya default. Begini cara saya mematikannya. The
set-specifier
fungsi khusus untuk XEmacs, dandefault-toolbar-visible-p
khusus untuk versi yang cukup baru-baru Emacs; menggunakancondition-case
mengurus kedua persyaratan. GNU Emacs menyediakan fungsi khusus jadi saya hanya menguji apakah fungsi itu tersedia.Beberapa nama wajah berubah karena versi. Gunakan
facep
untuk menguji ketersediaan nama wajah.Terkadang Anda mungkin ingin memuat paket yang bagus jika ada, dan tidak melakukan apa pun jika paket tidak tersedia.
require
memiliki argumen opsional untuk itu.Argumen ini diperkenalkan di GNU Emacs 20.4 dan tidak tersedia di XEmacs, jadi jika Anda ingin melangkah sejauh itu, Anda harus membungkusnya
condition-case
atau menggunakannyaload
(yang tidak memeriksa perpustakaan yang sudah dimuat) .Batasi ketergantungan versi ke fitur tingkat pengguna. Jangan gunakan fitur pemrograman yang lebih baru yang tidak tersedia di semua versi yang ingin Anda dukung: Anda harus menyediakan versi kompatibilitas untuk versi yang lebih lama, dan lebih mudah mempertahankan satu versi.
Terkadang Anda memang membutuhkan fitur di banyak tempat, dan itu tersedia di semua implementasi yang Anda pedulikan, tetapi dengan cara yang berbeda. Ini sebagian besar terjadi jika Anda ingin mendukung XEmacs dan GNU Emacs: mereka memiliki kecenderungan frustasi untuk menyalin fitur masing-masing tetapi tidak pada antarmuka mereka. Dalam hal ini, mendefinisikan fungsi kompatibilitas lebih mudah daripada pengujian pada saat digunakan.
Misalnya, kode berikut mendefinisikan fungsi yang mengembalikan sistem jendela dari frame saat ini, cara GNU modern, cara XEmacs modern, dan cara gaya lama ketika Anda tidak bisa menggabungkan frame terminal dan GUI dalam contoh yang sama.
Ketergantungan lingkungan
Tidak banyak kode yang harus bergantung pada platform. Variabel
system-type
menunjukkan sistem operasi. Saya menggunakannya secara eksklusif untuk mengaktifkan beberapa peretasanms-dos
(ya, file saya setua itu) danwindows-nt
.Anda mungkin ingin menambahkan direktori ke jalur pencarian yang dapat dieksekusi (
PATH
), tetapi itu biasanya paling baik dilakukan di luar Emacs, di.profile
sistem Anda untuk Unix-like dan melalui panel kontrol di Windows. Untuk menguji apakah program eksternal tersedia, hubungiexecutable-find
.Untuk kode yang perlu bertindak berbeda tergantung pada jenis GUI jika ada, periksa
window-type
atau penggantinya (lihat di atas).File inisialisasi
Untuk kompatibilitas maksimum, masukkan kode Anda
~/.emacs
. GNU Emacs mulai mencari di~/emacs.d
versi 22. XEmacs mulai mencari di~/.xemacs
dalam versi 21.4. Pendekatan alternatif adalah memasukkan kode kompatibilitas~/.emacs
dan menyelesaikannya dengan memuat file utama Anda. Letakkan di(setq load-home-init-file t)
suatu tempat untuk menghindari versi terbaru dari XEmacs yang menanyakan apakah Anda ingin memindahkan Anda.emacs
ke lokasi khusus XEmacs.Versi Emacs yang berbeda mungkin memiliki ekspansi yang berbeda dan tidak kompatibel untuk beberapa makro. Jadi jangan berbagi file byte-yang dikompilasi antar versi, kompilasi file pada setiap mesin.
Terkadang fitur sudah usang, tetapi Anda masih ingin menggunakannya karena hanya itu yang ada di beberapa versi lain yang ingin Anda dukung. Peringatan byte compiler berasal dari
byte-obsolete-variable
properti.¹ Secara relatif, dibandingkan dengan XEmac yang lebih lama.
sumber
(Komunitas wiki. Silakan tambahkan milik Anda!)
Jika ada fungsi, ditambahkan dalam versi Emacs yang lebih baru, yang ingin Anda gunakan, periksa apakah itu didefinisikan dengan
fboundp
, dan tentukan fungsi kompatibilitas jika tidak ditentukan.Ini dianggap ide yang buruk untuk memberikan fungsi kompatibilitas nama yang sama dengan fungsi sebenarnya, karena kode Elisp lainnya mungkin menggunakan
fboundp
trik yang sama . Dengan demikian, gunakan awalan untuk fungsi kompatibilitas, dan gunakandefalias
untuk nama yang sama jika didefinisikan. Misalnya:Jika beberapa konfigurasi hanya berlaku untuk OS tertentu, ada beberapa kemungkinan yang berbeda. Anda dapat memeriksa
system-type
variabel, yang kembalignu/linux
,darwin
,windows-nt
dan beberapa orang lainnya (lihat docstring).Anda mungkin tergoda untuk menggunakan
window-system
, meskipun doktringnya menyatakan bahwa "Penggunaan variabel ini sebagai boolean sudah usang", dan merekomendasikan untuk menggunakannyadisplay-graphic-p
. Perhatikan bahwa Emacs dapat menggunakan berbagai jenis tampilan untuk frame yang berbeda saat ini (misalnya satu frame di terminal dan lainnya di jendela "tepat"), jadi ini dapat menyebabkan kejutan. Gunakancurrent-frame-configuration
atauget-buffer-window-list
di elisp Anda untuk membuat pilihan yang tepat.Anda mungkin ingin memeriksa apakah Anda menjalankan di bawah rasa emacs yang tepat. Gunakan featureep untuk memeriksa varian. Misalnya:
Anda juga dapat menggunakannya untuk memeriksa modul tertentu yang dimuat. Sebagai contoh, jika Anda hanya menggunakan defun kecil dan mudah untuk mendefinisikan Common-lisp Anda mungkin memilih untuk mendefinisikan daripada membutuhkan. Misalnya:
Hindari menyimpan file .elc. Ini tidak kompatibel maju atau mundur dengan antara beberapa versi Emacs.
sumber
Jika Anda menggunakan fungsi dari
cl-lib
tetapi tidak ingin menggunakan versi non-namespace yang sudah usang, jadikan pustaka kompatibilitas cl-lib sebagai ketergantungan proyek Anda. Itu akan memungkinkan Anda untuk menggunakancl-
fungsi namespace tetapi mempertahankan kompatibilitas ke belakang.sumber
cl-lib
tetap ingin ? Apa kelebihannyacl
, yang sudah ada sejak setidaknya 20 tahun yang lalu?cl
sudah usang dan mungkin akan dihapus pada akhirnya. Menggunakannya dalam kode telah menyebabkan peringatan byte-compiler untuk waktu yang cukup lama. Saya pikir alasannya adalah bahwa mereka ingin menggunakan kembali beberapacl
nama (sepertidolist
) dengan semantik yang berbeda.