tl; dr: Використовуйте if
та власну функцію init:
(if (fboundp 'prog-mode)
(define-derived-mode your-cool-mode prog-mode "Cool"
"Docstring"
(your-cool--init))
(define-derived-mode your-cool-mode nil "Cool"
"Docstring"
(your-cool--init)))
Потім виконайте всі ініціалізації режиму в your-cool-init
.
Більш тривале пояснення:
Проблема полягає в тому, що офіційним способом написання похідного основного режиму є використання define-derived-mode
макросу:
(define-derived-mode your-cool-mode prog-mode ...)
Що стосується старшого Emacsen (до 24 років), це перерва, коли prog-mode
. І ви не можете використовувати (if (fboundp 'prog-mode) ...)
там, оскільки макрос очікує буквального символу, і він буде цитувати його для вас у розширенні.
define-derived-mode
використовує батьківство безліччю способів. Вам потрібно буде скопіювати всі ці дані у власному режимі визначення, щоб скористатися ними, і це є втомливим і схильним до помилок.
Тож єдиний спосіб - використовувати два різних define-derived-mode
твердження, залежно від того, prog-mode
існує чи ні. Це ставить перед вами проблему написання коду ініціалізації двічі. Звичайно, це погано, тому ви отримуєте це у своїй функції, як описано вище.
(Найкраще рішення - це, звичайно, відмовитися від підтримки 23.x і використовувати лексичне обстеження. Але я думаю, ви вже розглядали та відмовилися від цього варіанту. :-))
prog-mode
. Помітно, ви страждаєте від нестачі лексичного зв’язку.