emacs: помогите мне решить эту проблему с упорядочением автозагрузки с flymake и csharp - PullRequest
3 голосов
/ 17 ноября 2010

Как мне доставить модуль, который требует исправления 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 получит более гибкие процедуры инициализации / очистки и bob - твой дядя .

Но сейчас я хочу, чтобы 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 будет вызываться только после , а в список свойств 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 Ответ

1 голос
/ 17 ноября 2010

Если я правильно понимаю, если пользователь добавит это к своим .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))))
...