How to automatically install Emacs packages by specifying a list of package names?

后端 未结 11 2494
隐瞒了意图╮
隐瞒了意图╮ 2020-12-22 15:22

I am using package to manage my Emacs extensions. In order to synchronize my Emacs settings on different computers, I\'d like a way to specify a list of package

相关标签:
11条回答
  • 2020-12-22 15:40

    Based on comments by Profpatsch and answers below:

    (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-n-p (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)
    
    0 讨论(0)
  • 2020-12-22 15:40
    (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)
    
    0 讨论(0)
  • 2020-12-22 15:43

    Here's the code I use for 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)
    

    If you're not using MELPA you don't need to require it (and if you do melpa.el has got to be on your load-path (or installed via MELPA). The package db is not refreshed each time (as this would slow down the startup significantly) - only where there are uninstalled packages present.

    0 讨论(0)
  • 2020-12-22 15:45

    Call package-install with the package name as a symbol. You can find the package names for your packages by calling package-install interactively and completing on the name. The function package-installed-p will let you know if it's already been installed.

    For example:

    (mapc
     (lambda (package)
       (or (package-installed-p package)
           (package-install package)))
     '(package1 package2 package3))
    
    0 讨论(0)
  • 2020-12-22 15:47

    No one has mentioned Cask yet, but it is quite suitable for this task.

    Basically you create ~/.emacs.d/Cask listing the packages you want to install. For example:

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

    Running cask from the command line will install these packages for you, and any dependencies they need.

    Also, you can automatically update installed packages using cask update.

    0 讨论(0)
  • 2020-12-22 15:47

    I like checking if the user wants to install the packages first as done in this answer. Also I'm refreshing my package contents once before installing anything. I'm not sure if this is the best way, but I don't think the top answers were doing it for me.

    (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-n-p (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)))
    
    0 讨论(0)
提交回复
热议问题