Я пишу основной режим для языка программирования, но я хочу поддерживать более старые версии Emacs. prog-mode
относительно новый. Я хочу унаследовать, prog-mode
если он определен, но все же сделать что-то разумное в противном случае.
Какой лучший подход? Должен ли я использовать defalias
prog-mode
более старый Emacsen, или это будет мешать другим режимам, если они будут делать то же самое?
major-mode
prog-mode
version-compatibilty
Уилфред Хьюз
источник
источник
prog-mode
. Примечательно, что вы будете страдать от отсутствия лексической привязки.Ответы:
За счет дополнительной привязки символов верхнего уровня, есть очень аккуратное решение, которое позволяет избежать повторения
define-derived-mode
формы:Работает нормально в любом Emacs> = 23. Я придумал это
haml-mode
пару лет назад IIRC, и, похоже, он распространился оттуда на несколько других основных режимов. Главное, чтоdefine-derived-mode
макрос делает с символом родительского режима, - это генерирует код, который вызывает его функцию: в этом смыслеdefalias
новая переменная в точности эквивалентна псевдонимной функции.Одно предостережение в том, что это может сбить с толку
derived-mode-p
, поэтому код, который проверяет, является ли ваш режим полученным,prog-mode
может работать некорректно. На практике я не сталкивался с какими-либо проблемами: для такого кода более привычно подключатьсяprog-mode-hook
, который все еще запускается.(Как указывает Йорген в комментариях, он
define-derived-mode
также используетmode-class
свойство из символа родительского режима иdefalias
не будет копировать его. На момент написания этого свойства, кажется, его использовали только дляspecial-mode
.)Обновление: в эти дни я бы просто предложил требовать как минимум Emacs 24, так как старые версии давно устарели.
источник
prog-mode
, но не будет работать для каждого режима.define-derived-mode
копируетmode-class
свойство символа в дочерний режим.defalias
Будет не передать это имущество. Еслиmode-class
это актуально для вашего варианта использования, вам нужно скопировать / установить его вручную.mode-class
обозначает недвижимость.tl; dr: Используйте
if
и свою собственную функцию инициализации:Затем выполните инициализацию всего режима в
your-cool-init
.Более длинное объяснение:
Проблема в том, что официальным способом написания производного основного режима является использование
define-derived-mode
макроса:На старшем Emacsen (до 24) это ломается когда
prog-mode
. И вы не можете использовать его(if (fboundp 'prog-mode) ...)
там, потому что макрос ожидает буквальный символ и процитирует его для вас в расширении.define-derived-mode
использует родителя множеством способов. Вам нужно будет скопировать все из них в своем собственном определении режима, чтобы использовать их, и это утомительно и подвержено ошибкам.Таким образом, единственный способ - использовать два разных
define-derived-mode
утверждения, в зависимости от того,prog-mode
существует или нет. Это оставляет вас с проблемой написания вашего кода инициализации дважды. Что, конечно, плохо, поэтому вы извлекаете это в свою собственную функцию, как описано выше.(Лучшее решение - это, конечно, отказаться от поддержки 23.x и использовать лексическую область видимости. Но я думаю, что вы уже рассмотрели и отказались от этой опции. :-))
источник
prog-mode
в старшем Emacsen? Имеет ли смысл выводить изtext-mode
илиfundamental-mode
еслиprog-mode
нет в наличии?fboundp
сначала толькоdefine-derived-mode
утверждение? Тогда фактический режим с полным определением может быть получен из этого промежуточного режима? Таким образом, весь режим не должен быть определен дважды.fundamental-mode
эквивалентно производному отnil
(и действительноdefine-derived-mode
заменяетfundamental-mode
наnil
), ноtext-mode
не подходит, поскольку программный код не является текстовым. Большинство настроек по умолчаниюtext-mode
не имеют смысла в режимах программирования вне комментариев. Вот почемуprog-mode
был представлен в Emacs 24.define-derived-mode
определения вif
форме, только для промежуточного режима вместо окончательного режима. Вы бы заменилиdefun
для функции init наdefine-derived-mode
для конечного режима. Я не думаю, что это особенно предпочтительно. Вы также можете определитьprog-mode
себя, как предполагает первоначальный вопрос, но это может легко запутать другие режимы, которыеfboundp
проверяют наличие этого режима.define-derived-mode
утверждения. Пару лет назад я придумал решение, которое выложил в виде отдельного ответа, и, похоже, оно отлично работает в Emacs 23 и 24. Код, подобный тому, который используется в ряде популярных основных режимов.Я думаю, что использование тестирования
fboundp
имеет больше смысла.источник
Вы можете определить макрос-обертку,
define-derived-mode
который оценивает его аргументы.(Предупреждение: только минимально проверено.)
источник