8

I use the same configuration of emacs on multiple machines, and I want to use use-package to keep the packages the same on all machines. I have an init file in each machine's home directory that looks like this:

;;Set the custom file to Dropbox .emacscommon
(setq custom-file "~/Dropbox/.emacs.d/.emacscommon")

;;These are commands that should be common across systems.

(load "~/Dropbox/.emacs.d/.emacscommon")

And the beginning of .emacscommon has these lines:

;;; -*- mode: Emacs-Lisp; -*-

(eval-when-compile
  (require 'use-package))

(require 'use-package-ensure)
(setq use-package-always-ensure t)

(use-package auto-package-update
  :config
  (setq auto-package-update-delete-old-versions t)
  (setq auto-package-update-hide-results t)
  (auto-package-update-maybe))

When I start up Emacs, though, I get the following error.

Warning (initialization): An error occurred while loading ‘/Users/basil/.emacs’:

File is missing: Cannot open load file, No such file or directory, use-package

Checking the value of "load-path" via "describe-variable" gives a long list which includes "/Users/basil/.emacs.d/elpa/use-package-20190405.2047", so use-package appears to be accessible. Why can't Emacs find it? If I omit the use-package lines from .emacscommon, all other packages work just fine.

3
  • Do you compile .emacscommon?
    – npostavs
    May 19, 2019 at 15:42
  • Not sure the difference between compiling and loading. In my .emacs, I just tell it to load .emacscommon. Are you saying I shouldn't embed "require 'usepackage" in the eval-when-compile function?
    – sdklf9
    May 19, 2019 at 16:11
  • I just tried commenting out all of the lines I displayed above in my .emacscommon, and replacing them with (require 'usepackage). I get the same error.
    – sdklf9
    May 19, 2019 at 16:40

1 Answer 1

10

You may need a more complete "bootstrap" of use-pacakge. This is what I've picked up from somewhere else on SE.

;;{{{ Set up package and use-package

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

;; Bootstrap 'use-package'
(eval-after-load 'gnutls
  '(add-to-list 'gnutls-trustfiles "/etc/ssl/cert.pem"))
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(eval-when-compile
  (require 'use-package))
(require 'bind-key)
(setq use-package-always-ensure t)

;;}}}

First we load the package package, add MELPA, and initialize package. Then we add certs to gnutls. Next we test if Emacs thinks that use-package is installed, and install it otherwise. Note this is different than just seeing the package on our filesystem or in our load-path. I think that this is the key that you're missing.

Additionally, I'd recommend against using custom-file to store your "secondary init file". Experience has taught me that I'm happier if I give Emacs its own place to save settings. This is especially true when you put your init files under version control. Set it to a filename that you understand, and let Emacs read and write from it as necessary. So, in your case I'd do something like.

The init file on each machine:

;; this is my ~/.emacs.d/init.el

;; my common emacs settings are here
(load (expand-file-name "~/Dropbox/emacs.d/emacs-common-init.el"))

The init file common to every machine:

;; this is my ~/Dropbox/emacs.d/emacs-common-init.el"

;; prepend personal lisp directory to the load-path
(add-to-list 'load-path (expand-file-name "~/Dropbox/emacs.d/lisp"))

;; set a `custom-file` so Emacs leaves my init file alone
(setq custom-file (expand-file-name "~/.Dropbox/emacs.d/emacs-common-custom.el"))

;; Set up package and use-package

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

;; Bootstrap 'use-package'
(eval-after-load 'gnutls
  '(add-to-list 'gnutls-trustfiles "/etc/ssl/cert.pem"))
(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))
(eval-when-compile
  (require 'use-package))
(require 'bind-key)
(setq use-package-always-ensure t)

;; set up my nifty packages, themes, etc. 
;; [...]
1
  • 1
    This works great for me. I still don't fully understand it though - why wouldn't something like this be in the documentation? Does my multiple machine setup complicate this? But it seems that syncing across machines would be a very common use of use-package.
    – sdklf9
    May 20, 2019 at 14:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.