我现在正通过MELPA和Marmalade尽可能多地安装,我使用git管理我的〜/ .emacs.d。但是,我有git ignore * .elc文件。
这意味着当我在一个系统上安装软件包然后开始使用另一个系统时,git pull
只给我* .el文件。使用这些文件通常比使用* .elc。
我尝试将以下内容添加到〜/ .emacs.d / init.el:
;; load the packages we've installed. Note that package-install
;; byte-compiles the packages, but .elc is ignored by git so we force recompilation here
(byte-recompile-directory (expand-file-name "~/.emacs.d/elpa") 0)
(package-initialize)
不幸的是,这不等于package.el完成的编译。例如,如果我安装emacs-eclim,package.el不会编译emacs-eclim / company-emacs-eclim.el,我会收到以下错误:
Leaving directory `/home/wilfred/.emacs.d/elpa'
Compiling file /home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/company-emacs-eclim.el at Mon Mar 11 15:40:01 2013
Entering directory `/home/wilfred/.emacs.d/elpa/emacs-eclim-20130310.1237/'
company-emacs-eclim.el:35:1:Error: Cannot open load file: eclim
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-char'
Warning: assignment to free variable `mc--read-char'
Warning: reference to free variable `multiple-cursors-mode'
Warning: reference to free variable `mc--read-quoted-char'
Warning: assignment to free variable `mc--read-quoted-char'
Warning: reference to free variable `rectangular-region-mode'
Warning: reference to free variable `rectangular-region-mode'
如何使Emacs只编译与package.el相同的文件?
答案 0 :(得分:10)
package.el实际上使用完全相同的方法,它只是在启动时重新编译使错误更加明显。
使用的函数是package--make-autoloads-and-compile
,它调用:
(byte-recompile-directory pkg-dir 0 t)
所以问题中的原始代码是正确的。但是,要重新编译尚未编译的目录,可以执行以下操作:
(require 'dash)
(require 'f)
(defun was-compiled-p (path)
"Does the directory at PATH contain any .elc files?"
(--any-p (f-ext? it "elc") (f-files path)))
(defun ensure-packages-compiled ()
"If any packages installed with package.el aren't compiled yet, compile them."
(--each (f-directories package-user-dir)
(unless (was-compiled-p it)
(byte-recompile-directory it 0))))
(ensure-packages-compiled)
答案 1 :(得分:8)
我建议不要将软件包保留在版本控制中(你不会将.o文件置于版本控制之下,不是吗?)。这是我用来保持我的包同步的代码:
(setq jpk-packages
'(
ac-dabbrev
...
yasnippet
))
(package-initialize)
(add-to-list 'package-archives
'("melpa" . "http://melpa.milkbox.net/packages/"))
(add-to-list 'package-archives
'("org" . "http://orgmode.org/elpa/"))
(when (not package-archive-contents)
(package-refresh-contents))
(dolist (pkg jpk-packages)
(when (and (not (package-installed-p pkg))
(assoc pkg package-archive-contents))
(package-install pkg)))
(defun package-list-unaccounted-packages ()
"Like `package-list-packages', but shows only the packages that
are installed and are not in `jpk-packages'. Useful for
cleaning out unwanted packages."
(interactive)
(package-show-package-list
(remove-if-not (lambda (x) (and (not (memq x jpk-packages))
(not (package-built-in-p x))
(package-installed-p x)))
(mapcar 'car package-archive-contents))))
我把上面的内容放在init.el中(当然是在版本控制下),它安装了emacs启动时尚不存在的任何软件包。更新是从缓冲区package-list-packages
创建的。 package-list-unaccounted-packages
显示已安装但未在我的jpk-packages
列表中的所有软件包,并且可以轻松删除我从列表中删除的软件包。
要回答您的具体问题,我只需删除elpa目录并重新安装所有内容(使用上面的代码)。
答案 2 :(得分:6)
我更喜欢“如何自动重新编译任何过时的.elc文件”的更一般性问题的解决方案是使用https://github.com/tarsius/auto-compile
我曾经有一些自定义解决方案,涵盖了我遇到的大多数情况,但这个库涵盖了我正在做的所有事情以及更多。只需在加载任何其他内容之前对其进行初始化,然后对其进行排序。
关于不编译最初未编译的文件的原始问题,这就是0
的{{1}}参数所做的,所以你明确要求这种行为。默认行为是仅重新编译现有的过期.elc文件,因此您只需删除byte-recompile-directory
。
答案 3 :(得分:2)
我不知道关于字节编译包的具体问题的答案与package.el
完全相同。
但是,对于通过Melpa或marmalade安装扩展程序时在git中维护emacs配置目录的更一般问题,我建议你看看pallet,它是为解决这个问题而设计的。 / p>
答案 4 :(得分:1)
您遇到的问题只是在初始化软件包之前对文件进行字节编译。如果切换两行,问题就会消失。您收到的错误(Cannot open load file: eclim
)是因为~/.emacs.d/elpa/emacs-eclim-20130310.1237/
中尚未load-path
,package-initialize
会将其添加到您的load-path
(以及一些其他事情)。
答案 5 :(得分:1)
(byte-compile-file)对我有用。