简体   繁体   中英

Setting up emacs on new machine with init.el and package installation

Like presumably many emacs users I have my own emacs config file ~/.emacs.d/init.el for configuring emacs the way I like. So when I start using a new machine I copy my emacs config file to it. Now, the problem is that my emacs config file depends on a few packages that I have installed via the emacs package manager, but due to the missing packages I'm unable to successfully install packages.

I can of course start emacs without my config file ( emacs -q ), but then the problem is that only the default repo is available, so I cannot actually install the package I need to install in order to successfully start emacs with my config file.

So what I have usually done is to temporarily comment out stuff in my emacs config file, so that I'm able to successfully install the packages, and then I can uncomment it and restart emacs with my full config. But this is cumbersome, and usually takes a few tries before I comment out all the needed stuff. Surely there must be a better way that I'm missing?

You can place the initialization elisp that installs the packages you need in a separate file, then start emacs -q , then load and evaluate the packages elisp file.

I'm using the following code, in a file of its own, to handle packages. This code also defines the packages I'm using and allows for dynamically adding and loading packages.

If you load this file first thing from your init.el , then you would probably be able to just start Emacs as usual, and missing required packages will be installed automatically.

Update

I was somewhat bothered with the way I used defvar to define the package list variable. I've done some reading and fixed the code below—now it defvar a variable my-packages-package-list and then setq it to the list of packages to install. As far as I understand, this is a more idiomatic way of defining and using variables. As a result, this code now byte-compiled without any warnings.

For those who are interested, some information of using defvar and setq may be found here and in the Emacs` manual .

(require 'package)

(setq package-archives '(("gnu" . "https://elpa.gnu.org/packages/")
                         ;; ("marmalade" . "https://marmalade-repo.org/packages/")
                         ("melpa" . "https://melpa.org/packages/")
             ("org" . "https://orgmode.org/elpa/")))


(setq package-archive-priorities '(("melpa" . 10)
                   ("gnu" . 5)
                   ("org" . 2)
                   ;; ("marmalade" . 0)
                   ))

(package-initialize)

(when (not package-archive-contents)
  (package-refresh-contents))

;; the following code will install packages listed in myPackages if
;; they are not already installed
;; https://realpython.com/emacs-the-best-python-editor/

(defvar my-packages-package-list "List of custom packages to install.")

;;; this allows for dynamically update and install packages while
;;; Emacs is running, by modifying this list, and then evaluating it
;;; and tha mapc expression below it
(setq my-packages-package-list
      '(;; add the ein package (Emacs ipython notebook)
    ein

    ;; python development environment
    elpy

    ;; beutify python code
    py-autopep8

    ;; git emacs interface
    magit

    ;; debuggers front end
    realgud

    ;; multiple major mode for web editing
    ;; multi-web-mode

    ;; major mode for editing web templates
    web-mode

    ;; docker modes
    docker-compose-mode
    dockerfile-mode

    ;; list library for emacs
    dash
    ;; collection of useful combinators for emacs lisp
    dash-functional

    ;; major modes for yaml
    yaml-mode

    ;; major modes for markdown
    markdown-mode

    ;; major modes for lua
    lua-mode

    ;; major modes for fvwm config files
    fvwm-mode

    ;; treat undo history as a tree
    undo-tree

    ;; flychek
    ;; flychek-clojure
    ;; flychek-pycheckers

    ;; Clojure for the brave and true - below; amit - some packages
    ;; commented out by me until I'll be sure they are needed

    ;; makes handling lisp expressions much, much easier
    ;; Cheatsheet: http://www.emacswiki.org/emacs/PareditCheatsheet
    paredit

    ;; key bindings and code colorization for Clojure
    ;; https://github.com/clojure-emacs/clojure-mode
    clojure-mode

    ;; extra syntax highlighting for clojure
    clojure-mode-extra-font-locking

    ;; integration with a Clojure REPL
    ;; https://github.com/clojure-emacs/cider
    cider

    ;; allow ido usage in as many contexts as possible. see
    ;; customizations/navigation.el line 23 for a description
    ;; of ido
    ;; ido-ubiquitous

    ;; Enhances M-x to allow easier execution of commands. Provides
    ;; a filterable list of possible commands in the minibuffer
    ;; http://www.emacswiki.org/emacs/Smex
    ;; smex

    ;; project navigation
    ;; projectile

    ;; colorful parenthesis matching
    rainbow-delimiters

    ;; solarized theme
    solarized-theme

    ;; edit html tags like sexps
    ;; tagedit

    ;; help finding keys
    which-key

    ;; xkcd
    xkcd

    ;; Clojure exercises
    4clojure
))

(mapc #'(lambda (package)
    (unless (package-installed-p package)
      (package-install package)))
      my-packages-package-list)

What you can do is to declare packages you use. Then add some code that runs every time you open Emacs. It checks each package from that list if it has been installed or not. When it's not, it installs it.

A quick example from my config file :

;; first, declare repositories
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("marmalade" . "http://marmalade-repo.org/packages/")
        ("melpa" . "http://melpa.org/packages/")))

;; Init the package facility
(require 'package)
(package-initialize)
;; (package-refresh-contents) ;; this line is commented 
;; since refreshing packages is time-consuming and should be done on demand

;; Declare packages
(setq my-packages
      '(cider
        projectile
        clojure-mode
        expand-region
        helm
        jinja2-mode
        magit
        markdown-mode
        paredit
        wrap-region
        yaml-mode
        json-mode))

;; Iterate on packages and install missing ones
(dolist (pkg my-packages)
  (unless (package-installed-p pkg)
    (package-install pkg)))

And you're good.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM