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))))
Другие вопросы по тегам