【发布时间】:2013-09-13 09:58:03
【问题描述】:
我熟悉 load-path 和 require,但我想知道是否可以将我的 init.el 中的多个 require 语句合并到某种循环中,最终做点什么比如require-ing 给定目录中的所有文件。
有没有办法做到这一点?或者我应该保持原样,使用多个require 语句?
【问题讨论】:
标签: emacs directory elisp require
我熟悉 load-path 和 require,但我想知道是否可以将我的 init.el 中的多个 require 语句合并到某种循环中,最终做点什么比如require-ing 给定目录中的所有文件。
有没有办法做到这一点?或者我应该保持原样,使用多个require 语句?
【问题讨论】:
标签: emacs directory elisp require
我同意 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))))))
【讨论】:
require 只是load 的包装。两者应该没有区别,除非你load 一个库两次,这个函数应该防止这种情况发生。这个问题的唯一不同点可能是您加载目录文件的顺序。您可以尝试将 (directory-files dir t ".+\\.elc?$" t) 更改为 (directory-files dir t ".+\\.elc?$")(即删除最后一个参数),这将使您获得与接受的答案相同的排序。
load 传递了一个参数来禁用它。谢谢!
require 的 C 代码确实调用 load 并将 NOMESSAGE 设置为 t。我会相应地更新答案。
(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 一个功能。【讨论】:
你可以试试这样的:
(mapc (lambda (name)
(require (intern (file-name-sans-extension name))))
(directory-files ".emacs.d" nil "\\.el$"))
解释:
directory-files检索elisp文件列表
file-name-sans-extension删除扩展名
intern 和require 获取与文件基名关联的符号【讨论】: