Emacs Bulk install packages - emacs

I'm using This advice, trying to get Emacs to manage my packages for me. I cannot get Emacs to eval this bit of code, which should install all of my packages, but currently it does absolutely nothing. Is there some error in my elisp that I'm not seeing?
;;; Emacs is not a package manager, and here we load its package manager!
(require 'package)
(dolist (source '(("marmalade" . "http://marmalade-repo.org/packages/")
("elpa" . "http://tromey.com/elpa/")
;; TODO: Maybe, use this after emacs24 is released
;; (development versions of packages)
("melpa" . "http://melpa.milkbox.net/packages/")
))
(add-to-list 'package-archives source t))
(package-initialize)
;;; Required packages
;;; everytime emacs starts, it will automatically check if those packages are
;;; missing, it will install them automatically
(when (not package-archive-contents)
(package-refresh-contents))
(defvar tmtxt/packages
'(evil git-gutter monokai-theme magit markdown-mode evil-leader jedi evil-surround arduino-mode evil-nerd-commenter zeal-at-point))
(dolist (p tmtxt/packages)
(lambda ()
(when (not (package-installed-p p))
(package-install p))
(require p)))

The body of your dolist is a mere "lambda-expression", i.e. it immediately evaluates to a function which is immediately thrown away. Since you want the function's body to be executed, just remove the (lambda () ...) wrapper:
(dolist (p tmtxt/packages)
(when (not (package-installed-p p))
(package-install p))
(require p))

Related

can't install doom-modeline package on emacs

I'm new at emacs.
I'm trying to install doom-modeline using this command
M-x package-install RET doom-modeline RET
but it seems to not be in the package list
My init.el looks like this:
(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives
'(("melpa" ."https://melpa.org/packages/")
("elpa" . "https://elpa.gnu.org/packages/")
("org" . "https://orgmode.org/elpa/")))
(unless package--initialized
(package-initialize))
(unless package-archive-contents
(package-refresh-contents))
;; Initialize use-package on non-Linux platforms
(unless (package-installed-p 'use-package)
(package-install 'use-package))
(require 'use-package)
(setq use-package-always-ensure t)
;; Setup use-package
(unless (package-installed-p 'use-package)
(package-refresh-contents)
(package-install 'use-package))
(eval-when-compile
(require 'use-package))
(setq use-package-always-ensure t)
What can I do?
I suspect you just need to do this:
M-x package-refresh-contents RET
And then try installing it again.
Failing that, check that you don't already have it installed, as package-install doesn't offer to install the things you already have.

Emacs package install script cannot get packages

I want to use script to install all packages automatically when I move to new computer.
I write this script and emacs give me Package ‘highlight-symbol-’ is unavailable
#! emacs -q --script
;;; load package module
(require 'package)
(dolist (url '(("melpa" . "https://melpa.org/packages/")
("melpa-stable" . "http://stable.melpa.org/packages/")
))
(add-to-list 'package-archives url t))
(package-initialize)
;;; read package list from `packages` file
(defvar *packages-list '("highlight-symbol" "monokai-theme"))
(unless package-archive-contents
(package-refresh-contents))
;;; install packages
(dolist (package *packages-list)
(if (package-installed-p (intern package))
(princ (format "%s already installed \n" package))
(progn
(princ (format "%s is installing \n" package))
(package-install package)
(princ (format "%s installed \n\n")))))
What I tried:
Use emacs -q and try it into scratch. (package-install package) still has problem.
I don't know DONT-SELECT meaning in #'package-install, so I tried (package-install package nil) and (package-install package ""), they still have issues.
M-x package-install works well.
How can I fix it. And what is misunderstanding I made in this script.
Thank you!
Sorry, guys, it is a idiot question.
Answer is package-install accept symbol, but string.
I change code to (package-install (intern package) and then it works.

error: package.el not yet initialized

I'm in the middle of organising my .emacs file to better keep track of all the things I'm adding to it.
In doing so I've run into the error described in the title, and I'm not sure exactly why
Here's my .emacs file: (the load of comments are for my own reference)
;;;; Emacs config file
;; convenience function for loading multiple libs in a single call
(defun load-libs (&rest libs)
(dolist (lib libs)
(load-library lib)))
;; path to custom libraries as well as the libraries themselves
(add-to-list 'load-path "~/.emacs.d/lisp/")
(load-libs "convenience" "editor-behaviour")
;; Add support for the package manager
(require 'package)
;; Add various package archives
(add-to-list 'package-archives
'("marmalade" . "http://marmalade-repo.org/packages/")
'("melpa" . "http://melpa.milkbox.net/packages/"))
;; Installs packages if they aren't already
(package-refresh-and-install ; from convenience.el
'scala-mode2 'sbt-mode 'haskell-mode 'geiser 'auto-complete 'ac-geiser 'cider)
;; Initialise packages
(package-initialize)
;; libs dependent on the packages being initialized go here
(load-library "autocomplete-config")
;; Enable Haskell indentation
(custom-set-variables
'(haskell-mode-hook '(turn-on-haskell-indentation)))
Running emacs .emacs --debug-init gives me the following output:
Debugger entered--Lisp error: (error "package.el is not yet initialized!")
signal(error ("package.el is not yet initialized!"))
error("package.el is not yet initialized!")
package-installed-p(scala-mode2)
(if (package-installed-p pkg) nil (package-refresh-contents) (package-install pkg))
(while --dolist-tail-- (setq pkg (car --dolist-tail--)) (if (package-installed-p pkg) $
(let ((--dolist-tail-- pkgs) pkg) (while --dolist-tail-- (setq pkg (car --dolist-tail-$
package-refresh-and-install(scala-mode2 sbt-mode haskell-mode geiser auto-complete ac-$
eval-buffer(#<buffer *load*> nil "/Users/ElectricCoffee/.emacs" nil t) ; Reading at $
load-with-code-conversion("/Users/ElectricCoffee/.emacs" "/Users/ElectricCoffee/.emacs$
load("~/.emacs" t t)
#[0 "^H\205\262^# \306=\203^Q^#\307^H\310Q\202;^# \311=\204^^^#\307^H\312Q\202;^#\$
command-line()
normal-top-level()
Which suggests (by my understanding) that it has something to do with convenience.el, but all that's in there is this:
(defun package-refresh-and-install (&rest pkgs)
"Utility function to refresh package contents and install several packages at once"
(dolist (pkg pkgs)
(unless (package-installed-p pkg)
(package-refresh-contents)
(package-install pkg))))
So I'm not exactly sure where I'm making an error here... Any help?
You need to call package-initialize before you call package-refresh-and-install.

share emacs configuration between emacs 23 and emacs 24

I'm trying to put all my emacs configuration under version control in order to easily switch between different computers. Actually my preferred system is OSX (10.8.3) with emacs 24.3 from http://emacsformacosx.com/. But I can also work in other systems (more likely linux-based although different distribution ubuntu/scientific-linux) which generally are equipped with emacs 23.4. What I would like to have is a init file which check the version of emacs and the operating system, load the needed packages from emacs package manager.
So far my .emacs init file for emacs 24.3 on OSX is as follow
(require 'package)
(setq package-archives '(
("marmalade" . "http://marmalade-repo.org/packages/")
("org" . "http://orgmode.org/elpa/")
("melpa" . "http://melpa.milkbox.net/packages/")))
(package-initialize)
After that there are configuration (loaded separately as for example
(load "python-sy")
which uses some packages not installed as default: in particular
color-theme
org-mode
theme-changer
ess-site
magit
auctex
python.el (fgallina implementation)
plus some other things which relies in already built-in packages
I admit that I have no idea on how to start for having a .emacs init file which could be used indifferently in all the devices. Furthermore I also would like to have a way to load url-proxy-services based on the system configuration
(setq url-proxy-services '(("http" . "proxy.server.com:8080")))
Thank you for any help
Relevant variables are system-type and emacs-major-version. You can use something like the following
(if (>= emacs-major-version 24)
(progn
;; Do something for Emacs 24 or later
)
;; Do something else for Emacs 23 or less
)
(cond
((eq system-type 'windows-nt)
;; Do something on Windows NT
)
((eq system-type 'darwind)
;; Do something on MAC OS
)
((eq system-type 'gnu/linux)
;; Do something on GNU/Linux
)
;; ...
(t
;; Do something in any other case
))
Along with giornado answer, you can also put your package-specific settings in a way they will be evaluated only when the package is present by testing the (require) result. Example with the bbdb package:
(when (require 'bbdb nil t)
(progn ...put your (setq) and other stuff here... ))
For this situation I define few constants at the top of .emacs:
(defconst --xemacsp (featurep 'xemacs) "Is this XEmacs?")
(defconst --emacs24p (and (not --xemacsp) (>= emacs-major-version 24)))
(defconst --emacs23p (and (not --xemacsp) (>= emacs-major-version 23)))
(defconst --emacs22p (and (not --xemacsp) (>= emacs-major-version 22)))
(defconst --emacs21p (and (not --xemacsp) (>= emacs-major-version 21)))
Example usage:
(when --emacs24p
(require 'epa-file)
(epa-file-enable)
(setq epa-file-cache-passphrase-for-symmetric-encryption t) ; default is nil
)
Or:
(if --emacs22p
(c-toggle-auto-newline 1)
(c-toggle-auto-state 1))
etc.

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

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 names in .emacs file and then package could automatically search and install the packages, so that I don't need to install them manually by calling M-x package-list-packages. How to do that?
; 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)))
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
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)
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.
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.
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))
(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)
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)))
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))
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.
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)
Close to Nicholas's answer:
Packages package-1, package-2, and package-3 are installed if they're not present locally. If they are present, Emacs loads without any delay.
(setq package-archives ;
'(("gnu" . "https://elpa.gnu.org/packages/") ; declare repositories
("melpa" . "https://melpa.org/packages/"))) ;
(require 'package) ; activate packages
(package-initialize) ; initialize package facility
(setq my-packages
'(package-1
package-2
package-3))
(unless package-archive-contents ; unless packages are not available locally, dont refresh package archives
(package-refresh-contents)) ; refreshing package contents is time-consuming and should be done on demand
(dolist (pkg my-packages) ;
(unless (package-installed-p pkg) ; iterate over packages and install missing ones
(package-install pkg))) ;
;; other config below