如何通过指定软件包名称列表来自动安装Emacs软件包?

我正在使用package来pipe理我的Emacs扩展。 为了在不同的计算机上同步我的Emacs设置,我想要一个方法来在.emacs文件中指定一个软件包名称列表,然后package可以自动search和安装软件包,这样我就不需要手动安装它们通过调用Mx package-list-packages 。 怎么做?

 ; list the packages you want (setq package-list '(package1 package2)) ; list the repositories containing them (setq package-archives '(("elpa" . "http://tromey.com/elpa/") ("gnu" . "http://elpa.gnu.org/packages/") ("marmalade" . "http://marmalade-repo.org/packages/"))) ; activate all the packages (in particular autoloads) (package-initialize) ; fetch the list of packages available (unless package-archive-contents (package-refresh-contents)) ; install the missing packages (dolist (package package-list) (unless (package-installed-p package) (package-install package))) 

根据Profpatsch的评论和答案如下:

 (defun ensure-package-installed (&rest packages) "Assure every package is installed, ask for installation if it's not. Return a list of installed packages or nil for every skipped package." (mapcar (lambda (package) ;; (package-installed-p 'evil) (if (package-installed-p package) nil (if (y-or-np (format "Package %s is missing. Install it? " package)) (package-install package) package))) packages)) ;; make sure to have downloaded archive description. ;; Or use package-archive-contents as suggested by Nicolas Dudebout (or (file-exists-p package-user-dir) (package-refresh-contents)) (ensure-package-installed 'iedit 'magit) ; --> (nil nil) if iedit and magit are already installed ;; activate installed packages (package-initialize) 

Emacs 25.1+会自动跟踪用户安装的软件包在可定制的package-selected-packagesvariables中。 package-install将更新自定义variables,并且可以使用package-install-selected-packages函数安装所有选定的软件包。

这种方法的另一个便利的优点是你可以使用package-autoremove自动删除软件包package-selected-packages中没有包含package-selected-packages (尽pipe它会保留依赖关系)。

 (package-initialize) (unless package-archive-contents (package-refresh-contents)) (package-install-selected-packages) 

资料来源: http : //endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html

以下是我用于Emacs Prelude的代码:

 (require 'package) (require 'melpa) (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t) (package-initialize) (setq url-http-attempt-keepalives nil) (defvar prelude-packages '(ack-and-a-half auctex clojure-mode coffee-mode deft expand-region gist haml-mode haskell-mode helm helm-projectile inf-ruby magit magithub markdown-mode paredit projectile python sass-mode rainbow-mode scss-mode solarized-theme volatile-highlights yaml-mode yari yasnippet zenburn-theme) "A list of packages to ensure are installed at launch.") (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) 

如果你不使用MELPA,你不需要(如果你做melpa.el必须在你的load-path (或通过MELPA安装)。每次都不刷新包db(因为这个会显着减慢启动速度) – 只有存在卸载软件包的地方。

还没有人提到Cask ,但是它完全适合这个任务。

基本上你会创build~/.emacs.d/Cask列出你想安装的软件包。 例如:

 (source melpa) (depends-on "expand-region") (depends-on "goto-last-change") ; ... etc 

从命令行运行cask将为您安装这些软件包,以及他们所需的任何依赖关系。

此外,您可以使用cask update自动更新已安装的软件包。

以程序包名称作为符号调用package-install 。 您可以通过交互调用package-install并完成名称来find软件包的软件包名称。 函数package-installed-p会让你知道它是否已经安装。

例如:

 (mapc (lambda (package) (or (package-installed-p package) (package-install package))) '(package1 package2 package3)) 

我喜欢检查用户是否想要首先安装这个软件包,就像在这个答案中做的那样。 在安装任何东西之前,我还要刷新我的包内容。 我不确定这是否是最好的方法,但我不认为最重要的答案是为我做的。

 (setq required-pkgs '(jedi flycheck cider clojure-mode paredit markdown-mode jsx-mode company)) (require 'cl) (setq pkgs-to-install (let ((uninstalled-pkgs (remove-if 'package-installed-p required-pkgs))) (remove-if-not '(lambda (pkg) (y-or-np (format "Package %s is missing. Install it? " pkg))) uninstalled-pkgs))) (when (> (length pkgs-to-install) 0) (package-refresh-contents) (dolist (pkg pkgs-to-install) (package-install pkg))) 
 (require 'cl) (require 'package) (setq cfg-var:packages '( emmet-mode ergoemacs-mode flycheck flycheck-pyflakes monokai-theme py-autopep8 py-isort rainbow-mode yafolding yasnippet)) (defun cfg:install-packages () (let ((pkgs (remove-if #'package-installed-p cfg-var:packages))) (when pkgs (message "%s" "Emacs refresh packages database...") (package-refresh-contents) (message "%s" " done.") (dolist (p cfg-var:packages) (package-install p))))) (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t) (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t) (add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/") t) (add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t) (package-initialize) (cfg:install-packages) 

这是我的,它更短:)

 (mapc (lambda (package) (unless (package-installed-p package) (progn (message "installing %s" package) (package-refresh-contents) (package-install package)))) '(browse-kill-ring flycheck less-css-mode tabbar org auto-complete undo-tree clojure-mode markdown-mode yasnippet paredit paredit-menu php-mode haml-mode rainbow-mode fontawesome))