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

后端 未结 11 2483
隐瞒了意图╮
隐瞒了意图╮ 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:49
    ; 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)))
    
    0 讨论(0)
  • 2020-12-22 15:49

    I ran into a problem that nothing happened after adding (package-install 'org) into .emacs. I wanted to install the up-to-date version of org-mode and the built-in org-mode is quite old.

    I dug out the source code of package-install from Emacs 25.3.1. The function self already checks if a package is installed or not and refuses to install it if the package is already installed. So the check (unless (package-installed-p package) ...) from answer 10093312 is in fact uncalled for.

    (defun package-install (pkg &optional dont-select)
      "Install the package PKG.
    PKG can be a package-desc or a symbol naming one of the available packages
    in an archive in `package-archives'.  Interactively, prompt for its name.
    
    If called interactively or if DONT-SELECT nil, add PKG to
    `package-selected-packages'.
    
    If PKG is a package-desc and it is already installed, don't try
    to install it but still mark it as selected."
      (interactive
       (progn
         ;; Initialize the package system to get the list of package
         ;; symbols for completion.
         (unless package--initialized
           (package-initialize t))
         (unless package-archive-contents
           (package-refresh-contents))
         (list (intern (completing-read
                        "Install package: "
                        (delq nil
                              (mapcar (lambda (elt)
                                        (unless (package-installed-p (car elt))
                                          (symbol-name (car elt))))
                                      package-archive-contents))
                        nil t))
               nil)))
      (add-hook 'post-command-hook #'package-menu--post-refresh)
      (let ((name (if (package-desc-p pkg)
                      (package-desc-name pkg)
                    pkg)))
        (unless (or dont-select (package--user-selected-p name))
          (package--save-selected-packages
           (cons name package-selected-packages)))
        (if-let ((transaction
                  (if (package-desc-p pkg)
                      (unless (package-installed-p pkg)
                        (package-compute-transaction (list pkg)
                                                     (package-desc-reqs pkg)))
                    (package-compute-transaction () (list (list pkg))))))
            (package-download-transaction transaction)
          (message "`%s' is already installed" name))))
    

    The built-in org-mode also counts as installed and package-install refuses to install the newer version from ELPA. After spending some time reading package.el, I came up with the following solution.

    (dolist (package (package-compute-transaction
                      () (list (list 'python '(0 25 1))
                               (list 'org '(20171211)))))
      ;; package-download-transaction may be more suitable here and
      ;; I don't have time to check it
      (package-install package))
    

    The reason why it works is that package-* family functions handle the arguments differently based on whether if it is a symbol or a package-desc object. You can only specify version info for package-install via a package-desc object.

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

    Here's mine, it's shorter :)

    (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))
    
    0 讨论(0)
  • 2020-12-22 15:54

    Here's another way.

    ;; assure every package is installed
    (defun ensure-package-installed (&rest packages)
      (let ((user-required-packages
             (seq-remove
              (lambda (package) (package-installed-p package))
              packages)))
        (when user-required-packages
          (package-refresh-contents)
          (dolist (package user-required-packages)
            (package-install package)))))
    
    ;; list of packages to install
    (ensure-package-installed
     'try
     'which-key)
    
    0 讨论(0)
  • 2020-12-22 15:58

    Emacs 25.1+ will automatically keep track of user-installed packages in the customizable package-selected-packages variable. package-install will update the customize variable, and you can install all selected packages with the package-install-selected-packages function.

    Another convenient advantage of this approach is that you can use package-autoremove to automatically remove packages that are not included in package-selected-packages (though it will preserve dependencies).

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

    Source: http://endlessparentheses.com/new-in-package-el-in-emacs-25-1-user-selected-packages.html

    0 讨论(0)
提交回复
热议问题