我熟悉load-path
和require
,但我想知道是否可以将我的init.el中的多个require
语句合并成某种循环,最终做一些像在给定目录中require
所有文件的事情。
有没有办法做到这一点?还是应该保持原样,使用多个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))))))
(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
)不一定与文件的基本名称相同。或者该文件可能根本没有提供特性。(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
加载它
require
只是load
的一个包装器。除非您两次load
库,否则两者之间不应有任何区别,而此函数应该防止这种情况发生。对于这个问题,唯一的其他差异点可能是加载目录文件的顺序。您可以尝试将(directory-files dir t ".+\\.elc?$" t)
更改为(directory-files dir t ".+\\.elc?$")
(即删除最后一个参数),这将给您与接受的答案相同的排序。 - philsload
来禁用它。谢谢! - user1017523require
的C代码确实使用NOMESSAGE
设置为t
来调用load
。我会相应地更新答案。 - phils*scratch*
缓冲区中依次评估以下每个表达式:load-history
、(mapcar #'car load-history)
和(mapcar #'file-name-sans-extension (delq nil (mapcar #'car load-history)))
。 - phils