tl; dr: Используйте if
и свою собственную функцию инициализации:
(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
. Примечательно, что вы будете страдать от отсутствия лексической привязки.