14

My ~/.emacs (which you can find on GitHub) file loads several different Emacs packages and I would like them to be automatically installed as soon as Emacs starts up, if they are not already installed. This way if I have to reinstall my Ubuntu 16.04 operating system again I will not have to install each package myself manually using M-x package-install. Is there a way to write an ~/.emacs file so that it will automatically install all loaded packages on startup? I would like this to be done with the minimum of lines as I have over ten different packages loaded so if I have to add extra lines for each individual package it will make my ~/.emacs rather long.

5
  • 4
    There are several ways, but you should use github.com/jwiegley/use-package
    – bertfred
    Nov 26, 2016 at 14:28
  • Is it possible to load multiple packages in a single line with use-package, like I do on line 61 of my .emacs file?
    – Josh Pinto
    Nov 26, 2016 at 14:34
  • See package-install-selected-packages (requires Emacs 25.1).
    – politza
    Nov 26, 2016 at 16:38
  • Out of curiosity, why is it such a desirable property to have all of your packages listed on a single line? The only reason that you give is to keep your ~/.emacs file from getting "long." But if you are only loading a dozen packages, are you really concerned about the extra 11 lines in your config?
    – nispio
    Jul 4, 2017 at 22:49
  • Well this was a few months ago so I don't remember my specific thinking but I suspect it was along the lines of trying to minimize how much work is required when I add or subtract a package from the list that is automatically installed. Didn't want multiple lines being added to the file for each separate package installed.
    – Josh Pinto
    Jul 5, 2017 at 2:38

2 Answers 2

14

The easiest way is to install use-package.

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

(dolist (package '(use-package))
   (unless (package-installed-p package)
       (package-install package)))

Then

 (use-package paredit
   :ensure t)

The :ensure t is what ensures that the package is installed.

To just load ensure multiple packages are install

(dolist (package '(package-a package-b package-c))
 (unless (package-installed-p package)
   (package-install package))
   (require package))))
12
  • Can you specify multiple packages for it to load on a single line?
    – Josh Pinto
    Nov 26, 2016 at 14:38
  • If you mean use-package then no, but the expression above, can be
    – njdan5691
    Nov 26, 2016 at 14:48
  • Well my question is about multiple packages so please edit your answer so that it does just that, loads and if not present, automatically installs, multiple packages.
    – Josh Pinto
    Nov 26, 2016 at 14:49
  • the dolist can be changed to '(use-package 'some-other-package), but no other configuration can be done. I would recommend having a line for each package with use-package.
    – njdan5691
    Nov 26, 2016 at 14:50
  • 1
    @njdan5691 You should have something like (unless package-archive-contents (package-refresh-contents)), because unless you have somehow refreshed the package archives at least once, you can't install anything. Note that this hits the network. Also, the (require 'package) is redundant, because package-initialize is autoloaded.
    – jpkotta
    Dec 20, 2017 at 18:17
6

package.el keeps track of the packages you asked to install (as opposed to those that are auto-installed as dependencies) in the custom variable package-selected-packages.

So if you copy your ~/.emacs (in which Custom normally writes settings like that of package-selected-packages) to another system, all you should need to do is M-x package-install-selected-packages.

Of course, this doesn't automatically install the packages if they're absent, but I consider it a feature (I think it's a mistake for a program like Emacs to make network connections without an explicit request to do so). And it does save you the trouble of installing each package one by one.

2
  • Thanks. I just want to share my use case, which is different than that of the OP: I'm often transferring my dotfiles between machines (especially cloud, where they are created and killed all the time). The package directory is quite hefty, with elpy v-env and the kitchen sink, especially given old versions are not auto-trimmed, AFAIK. It's much easier to drop in a few small files and reinstall packages than carry them around.
    – kkm
    May 18, 2020 at 3:11
  • I forgot to mention one thing: (package-refresh-contents) needs to be invoked once before (package-install-selected-packages) when the local package directory is entirely missing, so that package distribution archive directories are cached first in subdirectories of its archive/ directory.
    – kkm
    May 18, 2020 at 4:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.