Emacs - 要求加载一个目录下的所有文件

4

我熟悉load-pathrequire,但我想知道是否可以将我的init.el中的多个require语句合并成某种循环,最终做一些像在给定目录中require所有文件的事情。

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

3个回答

4

我同意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”会产生许多快速的视觉变化(例如更改modeline颜色等),而不是一次性应用所有自定义内容。是否有一个钩子可以将其放置在其中,以便以较少的视觉惊喜应用文件内容? - user1017523
require只是load的一个包装器。除非您两次load库,否则两者之间不应有任何区别,而此函数应该防止这种情况发生。对于这个问题,唯一的其他差异点可能是加载目录文件的顺序。您可以尝试将(directory-files dir t ".+\\.elc?$" t)更改为(directory-files dir t ".+\\.elc?$")(即删除最后一个参数),这将给您与接受的答案相同的排序。 - phils
我其实自己找到了为什么它看起来不同的原因。原来是加载消息使得加载过程本身看起来是异步的,所以我传递了一个参数给 load 来禁用它。谢谢! - user1017523
很好的发现;require的C代码确实使用NOMESSAGE设置为t来调用load。我会相应地更新答案。 - phils
如果你仍然不确定这个表单的作用,可以在 *scratch* 缓冲区中依次评估以下每个表达式:load-history(mapcar #'car load-history)(mapcar #'file-name-sans-extension (delq nil (mapcar #'car load-history))) - phils
显示剩余2条评论

3
(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)不一定与文件的基本名称相同。或者该文件可能根本没有提供特性。
  • 只有在尚未加载过文件时(或您已经尝试过加载但失败了)才加载该文件。

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. 使用intern获取与文件基本名称相关联的符号,并使用require加载它

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接