Open markokocic opened 3 years ago
Another scenario is installing project.el
from GNU ELPA.
project.el
(use-package project
:pin gnu)
just keeps the built-in project.el
.
Just to reply to myself, I worked around this by having the following in my init file:
(defun mk/ignore-builtin (pkg)
(assq-delete-all pkg package--builtins)
(assq-delete-all pkg package--builtin-versions))
(mk/ignore-builtin 'org)
(use-package org ....)
This will ensure that org
is removed from the list of Emacs builtins before calling use-package
.
Since this is a relatively common problem, it would be good if we had use-package supportin this use case natively, by adding a new option like :ignore-builtin t
Maybe I'm missing something here, but I don't think :pin
ever supported upgrading packages? It sounds like you should just use M-x list-packages
and upgrade packages in the normal way here, no?
Regardless which version you installed or upgraded from the M-x list-packages
screen. Upon restarting emacs, use-package
will ignore :pin
and just load builtin version if it exists.
Snippet from https://github.com/jwiegley/use-package/issues/955#issuecomment-1183003690 works around this, but it would be nice if use-package
would natively support overriding builtin packages, since people that add use-package
snippet in their .emacs
file usually expect to load the latest version from elpa, like for any other package, and not from the emacs builtin disribution.
I use Emacs on multiple machines and copy my config manually without the elpa
directory. Thanks to use-package
, my init.el
downloads and installs everything I need the first time I start Emacs.
Except for org. I just tested again and even with :pin gnu
I get version 9.5.5 (9.6 is in ELPA as of the time of this writing).
As a user, :pin
seems like the intuitive way to solve this. :ignore-builtin t
feels more like a workaround, but I'd take that if it let me upgrade org with use-package
.
You know, I didn't think until after I wrote this to check if package--builtins
and package--builtin-versions
were dynamically scoped (they are). I could have replaced this whole macro with a let
statement. This works though and I've got work to do, so I'm leaving this here in case it helps someone else.
I can delete my ~/.emacs.d/elpa
directory, start Emacs, and have my full config including the ELPA version of org-mode. I assume this would work with other builtins that are also in ELPA.
(defmacro with-ignored-builtin-package (pkg &rest body)
"Ignore builtin PKG while executing BODY."
(declare (indent defun))
(let ((pb-orig (gensym))
(pbv-orig (gensym))
(ret (gensym)))
`(let ((,pb-orig package--builtins)
(,pbv-orig package--builtin-versions))
(unless package--builtins
(package-initialize))
(setf package--builtins
(assoc-delete-all ,pkg package--builtins))
(setf package--builtin-versions
(assoc-delete-all ,pkg package--builtin-versions))
(setf ,ret (progn ,@body))
(setf package--builtins ,pb-orig)
(setf package--builtin-versions ,pbv-orig)
,ret)))
Then all you have to do to get org-mode is something like this:
(with-ignored-builtin-package 'org
(use-package org
:pin gnu
:ensure t
:hook (org-mode . jds/org-mode-hook)
:init
(setq org-latex-classes nil)
:custom
(org-src-fontify-natively t)
(org-babel-load-languages '((C . t)
(emacs-lisp . t)
(fortran . t)
(lisp . t)
(maxima . t)
(perl . t)
(scheme . t)
(shell . t)))))
Remember to put it high in your config file so Emacs doesn't load the built-in org-mode first, otherwise you might get weird stuff like (void-function org-assert-version)
.
I have the following in my config where is
gnu
defined to point to gnu elpa repository.Expected result:
org-mode
is installed and loaded from the repository specified with:pin
.Actual result:
use-package
loads builtin version oforg
that is bundled with Emacs itself.Solutions: If :pin option is used,
use-package
should not allow loading specified package from other sources, including builtin packages.Note: This is related to #319 but not specific to
org-mode
since it applies to all packages.