emacs:帮我解决flymake和csharp的自动加载排序问题

时间:2010-11-16 21:23:40

标签: c# emacs flymake

如何提供需要修补flymake的模块,启动时间最短(=自动加载),对用户的emacs.el影响最小?

我正在研究flymake-for-csharp模块。它适用于flymake,教它如何使用C#代码文件更灵活。例如,flymake-for-csharp不仅可以使用makefile,还可以使用.csproj文件,也可以直接调用csc.exe。

模块工作正常。我现在正试图让它自动加载。

这是挑战。

要定义哪些语言可以使用flymake,flymake.el包含一个文件扩展名列表(.java,.cs,.c等)以及每种语言的init和cleanup例程。在默认的flymake.el中有一个C#条目,但正如我所说,默认的C#行为不够灵活。为了使其更灵活,我需要替换flymake alist中的C#条目,以便它指向flymake-for-csharp模块中的新init / cleanup逻辑。雅跟我?

在运行时修补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将获得更灵活的init / cleanup例程, 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 alist被修补以包含C#的新条目。

这种鸡与蛋的情况有什么办法吗?


我想到的一种方法是使用(require 'flymake-for-csharp)代替autoload。在flymake-for-csharp模块中,只运行补丁逻辑,然后以其他方式使用自动加载功能。这是个好主意吗?这是否需要我在2个不同的文件中提供flymake-for-csharp?

我想到的另一种方法是在flymake.el上使用eval-after-load。在那我可以提供补丁功能。结合这个问题:

  • 仅当flymake自动加载时才会起作用吗?当(外部)eval-after-load被评估时,已经加载的模块的eval-after-load中的逻辑会发生什么?

  • 如何在不影响用户的emacs.el的情况下执行此操作?


总之, 如何交付需要修补flymake的模块,启动时间最短(=自动加载),对用户的emacs.el影响最小?

1 个答案:

答案 0 :(得分: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 trick通过在;;;###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))))