Saya sedang menulis mode utama untuk bahasa pemrograman, tetapi saya ingin mendukung versi Emacs yang lebih lama. prog-mode
relatif baru. Saya ingin mewarisi dari prog-mode
jika sudah ditentukan, tetapi masih melakukan sesuatu yang masuk akal sebaliknya.
Apa pendekatan terbaik? Haruskah saya defalias
prog-mode
menggunakan Emacsen yang lebih lama, atau akankah itu mengganggu mode lain jika mereka melakukan hal yang sama?
major-mode
prog-mode
version-compatibilty
Wilfred Hughes
sumber
sumber
prog-mode
. Khususnya, Anda akan menderita karena kurangnya ikatan leksikal.Jawaban:
Dengan biaya pengikatan simbol level atas tambahan, ada solusi yang sangat rapi yang menghindari pengulangan
define-derived-mode
formulir:Berfungsi dengan baik di Emacs> = 23. Saya menemukan ini untuk
haml-mode
beberapa tahun yang lalu IIRC, dan tampaknya telah menyebar dari sana ke beberapa mode utama lainnya. Hal utama yangdefine-derived-mode
makro lakukan dengan simbol mode induk adalah menghasilkan kode yang memanggil fungsinya: dalam hal ini,defalias
membuat variabel baru persis sama dengan fungsi alias.Satu peringatan adalah bahwa ini dapat membingungkan
derived-mode-p
, jadi kode yang memeriksa untuk melihat apakah mode Anda berasalprog-mode
mungkin tidak berfungsi dengan benar. Dalam praktiknya saya belum mengalami masalah: lebih sering untuk menghubungkan kode seperti ituprog-mode-hook
, yang masih berjalan.(Seperti yang ditunjukkan Jorgen dalam komentar,
define-derived-mode
juga menggunakanmode-class
properti dari simbol mode induk, dandefalias
tidak akan menyalinnya. Pada saat penulisan, properti ini sepertinya hanya digunakan untukspecial-mode
.)Pembaruan: hari ini saya hanya menyarankan membutuhkan setidaknya Emacs 24, karena versi yang lebih lama sudah usang.
sumber
prog-mode
, tetapi tidak akan bekerja untuk setiap mode.define-derived-mode
menyalinmode-class
properti simbol ke mode anak. Thedefalias
akan tidak mentransfer properti ini. Jikamode-class
relevan dengan use case Anda, Anda perlu menyalin / mengaturnya secara manual.mode-class
ditunjukkan properti.tl; dr: Gunakan
if
dan fungsi init Anda sendiri:Kemudian lakukan semua inisialisasi mode di
your-cool-init
.Penjelasan yang lebih panjang:
Masalahnya adalah bahwa cara resmi menulis mode utama turunan adalah dengan menggunakan
define-derived-mode
makro:Pada Emacsen yang lebih tua (pra-24), ini rusak ketika
prog-mode
. Dan Anda tidak dapat menggunakannya di(if (fboundp 'prog-mode) ...)
sana karena makro mengharapkan simbol literal, dan akan mengutipnya untuk Anda dalam ekspansi.define-derived-mode
menggunakan orangtua dalam banyak cara. Anda harus menyalin semua itu dalam definisi mode Anda sendiri untuk memanfaatkannya, dan itu membosankan dan rentan kesalahan.Jadi satu-satunya cara adalah dengan menggunakan dua
define-derived-mode
pernyataan yang berbeda , tergantung pada apakahprog-mode
ada atau tidak. Itu membuat Anda kesulitan menulis kode inisialisasi Anda dua kali. Yang tentu saja buruk, jadi Anda mengekstraknya ke dalam fungsinya sendiri, seperti dijelaskan di atas.(Solusi terbaik tentu saja untuk menjatuhkan dukungan untuk 23.x dan menggunakan scoping lexical. Tapi saya kira Anda sudah mempertimbangkan dan menjatuhkan opsi itu. :-))
sumber
prog-mode
Emacsen yang lebih tua? Apakah masuk akal untuk berasal daritext-mode
ataufundamental-mode
jikaprog-mode
tidak tersedia?fboundp
terlebih dahulu, hanya dengandefine-derived-mode
pernyataan? Lalu mode aktual dengan definisi penuh dapat diturunkan dari mode menengah itu? Dengan begitu seluruh mode tidak harus didefinisikan dua kali.fundamental-mode
sama dengan berasal darinil
(dan memang,define-derived-mode
menggantikanfundamental-mode
dengannil
), sementaratext-mode
tidak sesuai, karena kode program bukan teks. Sebagian besar pengaturan default ditext-mode
tidak masuk akal dalam mode pemrograman di luar komentar. Inilah sebabnya mengapaprog-mode
diperkenalkan di Emacs 24.define-derived-mode
definisi dalamif
formulir, hanya untuk mode menengah dan bukan mode final. Anda akan menggantidefun
fungsi init dengan adefine-derived-mode
untuk mode akhir. Saya tidak berpikir ini lebih disukai. Anda juga dapat menentukanprog-mode
sendiri, seperti yang disarankan pertanyaan awal, tetapi itu dapat dengan mudah membingungkan mode lain yang bergantungfboundp
untuk memeriksa keberadaan mode itu.define-derived-mode
pernyataan berbeda diperlukan. Beberapa tahun yang lalu saya datang dengan solusi yang saya posting sebagai jawaban terpisah, dan tampaknya berfungsi dengan baik di kedua Emacs 23 & 24. Kode seperti itu digunakan dalam sejumlah mode utama populer.Saya pikir pengujian menggunakan
fboundp
lebih masuk akal.sumber
Anda bisa mendefinisikan makro pembungkus untuk
define-derived-mode
yang mengevaluasi argumennya.(Peringatan: hanya diuji minimal.)
sumber