7

我正在测试在 emacs init.el(Emacs 24.3) 中加载包。我按照作者的博客emacs prelude自动加载包,并将那里的代码复制到我init.el的底部。loop但是,我收到有关函数/符号的错误消息,其中显示:

Symbol's function definition is void: loop

有人可以解释如何修复代码吗?

我在网上搜索了一下,好像loop是一个宏cl-lib。我的猜测是loop缺少 for 的定义,我试图通过添加 来解决问题(require 'cl-lib),如代码所示,但错误仍然存​​在。还有其他关于类似错误消息的 SO 问题,例如:ELisp: cl-loop for "Symbol's value as variable is void"Symbol 的函数定义是 void: declare-function。但是错误消息对于缺少的内容有所不同,并且答案大多建议替代路线,例如使用较新版本的 emacs。

- 代码 -

(require 'package)
(add-to-list 'package-archives
  '("melpa-stable" . "http://stable.melpa.org/packages/") t)
(package-initialize)

;;; check & load packages
(defvar prelude-packages
  '( haskell-mode )
  "A list of packages to ensure are installed at launch.")

;;(require 'cl-lib) ;debug
(defun prelude-packages-installed-p ()
  (loop for p in prelude-packages
        when (not (package-installed-p p)) do (return nil)
        finally (return t)))

(unless (prelude-packages-installed-p)
  ;; check for new packages (package versions)
  (message "%s" "Emacs Prelude is now refreshing its package database...")
  (package-refresh-contents)
  (message "%s" " done.")
  ;; install the missing packages
  (dolist (p prelude-packages)
    (when (not (package-installed-p p))
      (package-install p))))

(provide 'prelude-packages)
;;; end load packages
4

1 回答 1

11

cl-lib包是在 Emacs 24.3 中引入的,并提供了许多 Common Lisp 特性,所有这些特性都带有cl-前缀。在此之前,使用这些功能的唯一方法是要求cl库,并使用不带前缀的名称,例如,loop而不是cl-loop. 但是,由于名称冲突的可能性,不鼓励这样做,并且通常建议尽可能使用前缀名称。

由于您使用的是 Emacs 24.3,因此解决此问题的“正确”方法是替换loopcl-loop和:returncl-return

(defun prelude-packages-installed-p ()
  (cl-loop for p in prelude-packages
           when (not (package-installed-p p)) do (cl-return nil)
           finally (cl-return t)))

(您不需要(require 'cl-lib), 因为cl-loopcl-return是自动加载的。)

或者,您可以添加(require 'cl)以访问无前缀名称,并保留代码原样。这也适用于早期的 Emacs 版本。


我不禁注意到这个函数可以写得更简洁:

(defun prelude-packages-installed-p ()
  (cl-every 'package-installed-p prelude-packages))

cl-every关于加号cl-libevery加号的相同问题cl也适用。

于 2015-06-15T15:23:57.990 回答