emacs: помогите мне решить эту проблему с автозагрузкой flymake и csharp
Как я могу доставить модуль, который требует исправления flymake, с минимальным временем запуска (= автозагрузка) и минимальным воздействием на emacs.el пользователя?
Я работаю над модулем flymake-for-csharp. Он работает с flymake, учит тому, как быть более гибким с файлами кода C#. Например, вместо использования make-файла flymake-for-csharp может также использовать файл.csproj или напрямую вызывать csc.exe.
Модуль работает отлично. Я сейчас пытаюсь сделать его автозагрузку правильно.
вот проблема.
Чтобы определить, какие языки получают flymake'd, flymake.el включает список расширений файлов (.java,.cs,.c и т. Д.) Вместе с процедурами инициализации и очистки для каждого из этих языков. В файле flymake.el по умолчанию есть запись для C#, но, как я уже сказал, поведение C# по умолчанию недостаточно гибкое. Чтобы сделать его более гибким, мне нужно заменить запись C# в списке flymake, чтобы он указывал на новую логику init/cleanup в модуле flymake-for-csharp. Я со мной?
Нет проблем с исправлением alist во время выполнения. Это выглядит так:
(let (elt
(csharp-entry nil)
(masks flymake-allowed-file-name-masks))
;; Find the existing C# entry
(while (consp masks)
(setq elt (car masks))
(if (string= "\\.cs\\'" (car elt))
(setq csharp-entry elt))
(setq masks (cdr masks)))
;; remove the original entry for C# ...
(if csharp-entry
(setq flymake-allowed-file-name-masks
(delete csharp-entry flymake-allowed-file-name-masks)))
;; Now add a new entry for C#, with the custom init and cleanup methods.
(setq flymake-allowed-file-name-masks
(cons
'("\\.cs\\'" flymake-for-csharp-init flymake-for-csharp-cleanup)
flymake-allowed-file-name-masks)))
Долгосрочное решение состоит в том, чтобы убедить авторов flymake и emacs принять логику, которая в настоящее время используется в flymake-for-csharp. Тогда alist получит более гибкие процедуры инициализации и очистки, и Боб станет вашим дядей.
Но сейчас я хочу, чтобы flymake-for-csharp работал с существующим (встроенным) flymake.el. В этом и заключается проблема: как я могу сделать автозагрузку flymake-for-csharp, все еще исправляя alist?
В идеале я бы хотел, чтобы пользователь emacs.el выглядел так:
(autoload 'flymake-for-csharp-init "flymake-for-csharp" nil nil)
... с небольшим (eval-after-load ..
раздел.
Но вы видите, функция flymake-for-csharp-init
будет вызван только после того, как alist от flymake пропатчен, чтобы включить новую запись для C#.
Есть ли способ обойти ситуацию с курицей и яйцом?
один из подходов, о котором я подумал, заключался в использовании (require 'flymake-for-csharp)
вместо autoload
, В этом модуле flymake-for-csharp запустите только логику патча, а затем каким-то образом используйте автозагрузку для остальных функций. Это было бы хорошей идеей? Требуется ли от меня доставка flymake-for-csharp в двух разных файлах?
Другой подход, о котором я подумал, заключался в использовании eval-after-load
на flymake.el. В этом я мог бы предоставить функцию патча. Пара вопросов с этим:
Будет ли это работать, только если Flymake загружается? Что происходит с логикой в eval-after-load для модуля, который уже загружен, когда (внешний) eval-after-load eval'd?
Как бы я сделал это, не влияя на emacs.el пользователя?
Таким образом, как я могу доставить модуль, который требует исправления flymake, с минимальным временем запуска (= автозагрузка) и минимальным воздействием на emacs.el пользователя?
1 ответ
Если я правильно понимаю, пользователь должен добавить это к своим .emacs
решит проблему:
;;;###autoload
(eval-after-load "flymake" '(code-that-patches-flymake-allowed-file-name-masks))
(autoload 'flymake-for-csharp-init "flymake-for-csharp" nil nil)
Теперь, если вы работаете с людьми, использующими ваш пакет, вы можете использовать трюк loaddefs.el для автоматической загрузки этого кода пользователем, поставив ;;;###autoload
комментарий прямо перед eval-after-load
линии в вашем пакете, а затем восстановить loaddefs.el
файл.
Но, если вы надеетесь на решение для общего использования в Интернете, вам нужно, чтобы пользователь имел обе строки в своем .emacs
,
Комментарий к вашему коду очистки, я думаю, его можно упростить до:
(let ((csharpentry (assoc "\\.cs\\'" flymake-allowed-file-name-masks)))
(when csharpentry
(setcdr csharpentry '(flymake-for-csharp-init flymake-for-csharp-cleanup))))