Since Emacs 25.1 package.el tracks which packages I installed manually. The reasons are outlined in a much better way than I could do this in this article.
That’s nice and dandy, but whenever I try out a package my custom file changes, because “
packages-selected-packages” changes and is unfortunately written there.
So whenever I install something, even experimental things, this:
’(package-selected-packages (quote (ivy-hydra flx ivy magit font-lock ox-reveal company-quickhelp ox-gfm org-plus-contrib org company-c-headers erc-hl-nicks notmuch company helm-flycheck zenburn-theme eros elfeed flycheck rust-mode helm-flyspell kurecolor toml-mode git-timemachine zeal-at-point rainbow-mode dumb-jump column-marker web-mode pug-mode markdown-mode lua-mode js2-mode go-mode d-mode dtrt-indent clean-aindent-mode pdf-tools htmlize helm-swoop helm-descbinds which-key iflipb avy-zap smartscan avy expand-region undo-tree keyfreq dash paradox use-package))))
changes. And also often in a way that a git merge conflict is almost certain.
Stopping changes to the custom.el file
I already track my packages manually: with “
:ensure t” lines in “
(use-package” clauses. So certainly I can get rid of the tracking in custom.el?!?!
And it is quite easy, I found the followed tip how to make this:
(defun package--save-selected-packages (&optional VALUE opt) nil)
This is the function in package.el that normally saves the value to the customization system. By redefining it to a dummy function, nothing will be saved. My custom.el stays clean.
Telling package.el about manually installed packages
That was easy. But now “
package-list-packages” (and also “
paradox-list-packages”) list all packages as “dependency”, none as “installed”. Without the saved values from “
packages-selected-packages” package.el doesn’t know that what packages I have installed manually and which it installed automatically.
So we must transfer the information from use-packages’s “
:ensure t” to package.el !
To do this, simply redirect use-packages’ handler for the “
:ensure” clause to your own function. Save those packages that have an ensure clause into “
packages-selected-packages” and finally call the original function:
(defun my-use-package-ensure-elpa (name ensure state context &optional no-refresh) (let ((package (or (when (eq ensure t) (use-package-as-symbol name)) ensure))) (when package (add-to-list 'package-selected-packages package))) (use-package-ensure-elpa name ensure state context no-refresh)) (setq use-package-ensure-function #'my-use-package-ensure-elpa)