我想在正确安装特定软件包的同时自定义环境。如何检查elisp中是否安装了某个软件包? 像这样的东西?:
(if (require 'ecb)
(progn (setq ....))
(message "ECB not installed!"))
答案 0 :(得分:37)
tripleee的答案是错误处理的一个方便示例,但在此实例中是不必要的。
(when (require 'some-library nil 'noerror)
do-things)
'noerror
可以是任何非零值,但当然这种方式更具描述性。我经常看到使用:noerror
,但我不知道在符号上使用关键字参数是否有任何特殊优势(评论,任何人?我很有兴趣知道)。
require是
C source code
中的内置函数。(需要FEATURE和可选的FILENAME NOERROR)
如果未加载功能FEATURE,请从FILENAME加载 如果FEATURE不是列表
features
的成员,则为特征
没装;所以加载文件FILENAME 如果省略FILENAME,则FEATURE的打印名称将用作文件名,
并且load
会尝试加载此名称,并附加后缀.elc
或
.el
,按此顺序排列。不使用没有附加后缀的名称 有关后缀的完整列表,请参阅get-load-suffixes
如果可选的第三个参数NOERROR是非零的,则 如果找不到文件,则返回nil,而不是发出错误信号 通常返回值为FEATURE 加载FILENAME的开始和结束时的正常消息被抑制。
答案 1 :(得分:8)
(require)
如果失败则会抛出错误。这应该就是你所需要的一切。
如果您只想在可用的情况下配置ECB的行为,请主要查看向ecb-hook
添加内容 - 这是有条件地配置Emacs包的常规方法。
如果没有可用的挂钩,或者您想由于某种原因手动滚动,请尝试
(eval-after-load 'ecb '(setq ecb-be-more-like-better-yes-p t))
如果你真的想亲自动手,你可以从失败的require
中捕获错误:
(condition-case nil
(progn
(require 'ecb)
(setq ecb-be-more-like-better-yes-p t) )
(file-error (message "ECB not available; not configuring") ))
请注意,condition-case
会抓住file-error
内的任何progn
,因此您需要确保不在内部执行任何其他文件操作。最后,您可能只想将require
放在condition-case
内,并将其用作原始if
形式的条件,但这已经失控......
(if (condition-case nil (require 'ecb) (error nil))
(setq ecb-be-more-like-better-yes-p t)
(message "ECB not available; not configuring") )
答案 2 :(得分:6)
为什么不使用“featurep”?
(featurep FEATURE &optional SUBFEATURE)
如果此Emacs中存在FEATURE,则返回t。
(if (featurep 'ecb)
(message "ECB is there!"))
答案 3 :(得分:3)
对于想知道如何安装 package.el 软件包的人,请使用package-installed-p
。
答案 4 :(得分:1)
最简单的答案是使用其他答案中所述的require
和eval-after-load
。
然而,这并不总是方便的,例如在模式挂钩调用的函数中,想要激活另一个次要模式但仅在安装了它的包时。在这种情况下,featurep
是相关的。
Emacs软件包越来越多地使用自动加载来缩短启动时间。如果您使用require
测试包的存在,那么您将承担加载文件的成本。如果使用ELPA / MELPA / Marmalade软件包(默认情况下从版本24开始提供),则许多软件包可能处于尚未卸载的状态,但带有自动加载的软件包foo
将提供功能foo-autoloads
。我编写了一个函数,可用于测试包是否可用于已加载或设置为自动加载。
(defun autofeaturep (feature) "For a feature symbol 'foo, return a result equivalent to: (or (featurep 'foo-autoloads) (featurep 'foo)) Does not support subfeatures." (catch 'result (let ((feature-name (symbol-name feature))) (unless (string-match "-autoloads$" feature-name) (let ((feature-autoloads (intern-soft (concat feature-name "-autoloads")))) (when (and feature-autoloads (featurep feature-autoloads)) (throw 'result t)))) (featurep feature))))
答案 5 :(得分:0)
这个问题已经晚了四年,但是......这是一个简单的宏,可以为你做到这一点。
(defmacro when-feature-loaded (feature &rest body)
"Executes BODY if and only if FEATURE is loaded."
(declare (indent defun))
`(when (featurep ,module)
@,body))
例如:
(when-feature-loaded 'foo
(message "foo is loaded!"))
这是" else"的另一个版本如果你需要处理它的话。
(defmacro if-feature-loaded (module then-form else-form)
"Executes THEN-FORM if and only if MODULE is already loaded, otherwise executes ELSE-FORM."
(declare (indent 2))
`(if (featurep ,module)
,then-form
,else-form))