【问题标题】:Emacs - Require All Files In a DirectoryEmacs - 需要目录中的所有文件
【发布时间】:2013-09-13 09:58:03
【问题描述】:

我熟悉 load-pathrequire,但我想知道是否可以将我的 init.el 中的多个 require 语句合并到某种循环中,最终做点什么比如require-ing 给定目录中的所有文件。

有没有办法做到这一点?或者我应该保持原样,使用多个require 语句?

【问题讨论】:

    标签: emacs directory elisp require


    【解决方案1】:

    我同意 Drew 的观点,即您想在这种情况下使用 load。此函数基于 Drew 的代码,进行了一些调整以避免在同时存在 .el 和 .elc 版本时重新加载库。

    (defun my-load-all-in-directory (dir)
      "`load' all elisp libraries in directory DIR which are not already loaded."
      (interactive "D")
      (let ((libraries-loaded (mapcar #'file-name-sans-extension
                                      (delq nil (mapcar #'car load-history)))))
        (dolist (file (directory-files dir t ".+\\.elc?$"))
          (let ((library (file-name-sans-extension file)))
            (unless (member library libraries-loaded)
              (load library nil t)
              (push library libraries-loaded))))))
    

    【讨论】:

    • 我会使用“load”,但这样做会使 Emacs 的启动方式与使用“require”不同。具体来说,不是一次应用我的所有自定义设置,而是在“加载”时发生许多快速的视觉更改(例如更改模式线颜色等),而“要求”不会发生。有没有一个钩子可以让我在应用文件内容时减少视觉上的惊喜?
    • require 只是load 的包装。两者应该没有区别,除非你load 一个库两次,这个函数应该防止这种情况发生。这个问题的唯一不同点可能是您加载目录文件的顺序。您可以尝试将 (directory-files dir t ".+\\.elc?$" t) 更改为 (directory-files dir t ".+\\.elc?$")(即删除最后一个参数),这将使您获得与接受的答案相同的排序。
    • 我自己确实发现了它看起来不一样的原因。事实证明,加载消息使加载过程本身看起来是异步的,所以我向load 传递了一个参数来禁用它。谢谢!
    • 好定位; require 的 C 代码确实调用 load 并将 NOMESSAGE 设置为 t。我会相应地更新答案。
    • 感谢您提供上述功能——它非常有用。能否请您解释一下 mapcar 在 (mapcar #'file-name-sans-extension (delq nil (mapcar #'car load-history)) 中的用法,特别是“#”的意义。
    【解决方案2】:
    (let ((loaded  (mapcar #'car load-history)))
      (dolist (file  (directory-files "~/.emacs.d" t ".+\\.elc?$"))
        (unless (catch 'foo
                  (dolist (done  loaded)
                    (when (equal file done) (throw 'foo t)))
                  nil)
          (load (file-name-sans-extension file))
          (push file loaded))))
    
    • 使用load,而不是require,因为功能名称(来自provide)不一定与文件的基本名称相同。或者该文件甚至可能没有provide 一个功能。
    • 仅在文件尚未加载(或您已尝试加载)时加载文件。

    【讨论】:

      【解决方案3】:

      你可以试试这样的:

      (mapc (lambda (name)
              (require (intern (file-name-sans-extension name))))
            (directory-files ".emacs.d" nil "\\.el$"))
      

      解释:

      1. 使用directory-files检索elisp文件列表
      2. 使用file-name-sans-extension删除扩展名
      3. 使用internrequire 获取与文件基名关联的符号

      【讨论】:

        猜你喜欢
        • 2015-09-17
        • 2011-05-30
        • 2014-08-12
        • 2013-10-30
        • 1970-01-01
        • 2017-11-27
        • 2017-12-04
        • 1970-01-01
        • 2011-11-05
        相关资源
        最近更新 更多