WARNING: COMPLETELY WRONG/OBSOLETE, SEE THIS ANSWER!
The correct solution is to use straight.el
, a package manager that I wrote to solve this problem. You can get as elaborate as you want with ensuring the portability of your setup.find more details about this in (I, personally, go for the "complete overkill" solutionanother answer to this question.)
Install packages automatically on Emacs startup
(Note: while I quite like my current setup, use-package
looks extremely nice, and I'll probably be switching to it someday. See the other answers to this question.)
This answer, which was written months before I started work on straight.el
, previously described a strictly inferior way of achieving a partial solution. This approach is whatdescribed briefly below; I do in myno longer recommend it.
Even if you don't want to use initstraight.el
, you should at least adopt (full versionuse-package
. here(Not that the two are mutually exclusive—I believe the cleanest setup comes from using both.)
Start by defining a list of packages in your init-file:
;;; Here we are using the defvar-nil-setq pattern described in [1],
;;; which makes it so that changes to this list will be picked up by a
;;; reload of init.el (M-RET r).
;;;
;;; [1]: http://ergoemacs.org/emacs/elisp_defvar_problem.html
(defvar radianmy-packages nil "The packages required by Radian.")
(setq radian-packages
'(
ace-jump-mode ; quickly jump to words, characters, or lines onscreen
aggressive-indent ; keep code correctly indented at all times
.
.
.
projectile ; quickly jump to files organized by projectavy
undo-tree ; more intuitive and powerful undo/redo
))
.
;; The cl-lib library provides `cl-every', which is used in the code
;; for determining if any packages need to be installed.
(require 'cl-lib)
;;; The following code will install any packages specified in
;;; `radian-packages' that are not already installed. It will only
;;; call `package-refresh-contents' if it is necessary to install a
;;; new package. The mainprojectile
logic is based on [1].
;;;
;;; [1]: http://batsov.com/articles/2012/02/19/package-management-in-emacs-the-good-the-bad-and-the-ugly/
;; Since `package-archives', `package-pinnedundo-packages', andtree
;; `package-installed-p' are not autoloaded, we must explicitly load
;; package.el before using any of them.
(require 'package)
;; Add package repositories. GNU is the default repository; MELPA is
;; necessary to get most"List of the packages we are interested in.
(setq package-archives
to be installed '(("gnu"at .Emacs "http://elpa.gnustartup.org/packages/")
("melpa" . "https://melpa.org/packages/")))
;; Initialize package.el. This is necessary to use
;;
Then install them automatically:
(require `package-installed'cl-p'.lib)
(package-initialize)
;; If any of the packages in `radian-packages' are not installed...
(unless (cl-every 'package#'package-installed-p radianmy-packages)
;; ... then make sure that we know about the latest versions of all
;; the packages...
(package-refresh-contents)
;; ... and install any packages that aren't already installed.
(dolist (package radianmy-packages)
(unless (package-installed-p package)
(package-install package))))
KeepIf you keep your init.el
file under version control and publish it to Github (or Dropbox, or ...). For example, you can see my repository here. When you switch to a new machine, clone the repository and link ~/.emacs.d/init.el
to the file in the repository. This is what I do (except that the linking part is automated, more on that later).
Alternatively, you can clone the repository directly to your ~/.emacs.d
folder. The disadvantage of this is that you have to make surethen syncing it to put everything Emacs might create in your .gitignore
.
Either way, with this code installed, you can just drop your init.el
file on another machine and start Emacs. All ofwill result in your packages will bebeing installed automatically. Instead of using M-x package-install
Of course, you simply add the package name to the list defined in init.el
and reload the file. Then the package is not onlyversions that are installed, but is guaranteed to always will be installed on any machine where you are using that init.el
file.
Alternativelycompletely different, you can simply keep your entire ~/.emacs.d
folder under version control (or at least most of it). This way you can have 100% control overand your setup, instead of relying on the MELPA servers to be able to download packages when they need toconfiguration can't be installed. The disadvantage of this is that you needexpected to manually update allwork out of your packages and createthe box as a commit every time you update anything.
You mention you have other .el
files you've written yourselfresult. Personally, I prefer to keep everything inThis is a single file (namely,fundamental flaw of initpackage.el
). I think this makes things simpler. But if you have other files, then you can just keep these under version control as well, and you will get them when you clone from another machine.
Automate deployment on another machine
This is one of the overkill partreasons why this approach is bad. You can see my scriptSee again herestraight.el
. Given an arbitrary OS X machine, it will installNote also that the correct versions of all dependencies, back up any existing dotfiles, and make sure everything is symlinked correctly.
I actually go a step farther, and separate my dotfiles into two groups: public and private. My public dotfiles are published on Github as Radian, and they are meant to be usage by a wide range of people with different preferencescode outlined above separates your package list from me. I host my private dotfiles in Dropbox: these areyour configuration for settings specific to me and my filesystem, weird hacksthose packages, and other randommaking it harder to keep track of things.
To get started on a new machine, then, I install Dropbox, clone Radian, and run the setup script in your init-file. I'll be prompted for the location of my private dotfiles folder, and everything else will be set up automaticallyThis is another major disadvantage. I can then hit the ground running immediatelySee again use-package
.