2018-06-11 23:18:15 +02:00
|
|
|
;;; core/core-packages.el -*- lexical-binding: t; -*-
|
2017-02-19 06:59:55 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(require 'core-modules)
|
|
|
|
|
2018-05-24 21:17:23 +02:00
|
|
|
;; Emacs package management is opinionated, and so am I. I've bound together
|
|
|
|
;; `use-package', `quelpa' and package.el to create my own, rolling-release,
|
|
|
|
;; lazily-loaded package management system for Emacs.
|
2017-02-11 06:00:08 -05:00
|
|
|
;;
|
2017-07-14 15:23:12 +02:00
|
|
|
;; The three key commands are:
|
|
|
|
;;
|
2018-06-17 21:35:58 +02:00
|
|
|
;; + `bin/doom install`: Installs packages that are wanted, but not installed.
|
|
|
|
;; + `bin/doom update`: Updates packages that are out-of-date.
|
|
|
|
;; + `bin/doom autoremove`: Uninstalls packages that are no longer needed.
|
2017-07-14 15:23:12 +02:00
|
|
|
;;
|
|
|
|
;; This system reads packages.el files located in each activated module (and one
|
2017-11-13 18:03:36 +01:00
|
|
|
;; in `doom-core-dir'). These contain `package!' blocks that tell DOOM what
|
2017-07-14 15:23:12 +02:00
|
|
|
;; plugins to install and where from.
|
2017-01-16 23:15:48 -05:00
|
|
|
;;
|
2017-01-28 02:02:16 -05:00
|
|
|
;; Why all the trouble? Because:
|
2019-05-12 22:09:52 -04:00
|
|
|
;; 1. *Scriptability:* I live in the command line. I want a shell-scriptable
|
|
|
|
;; interface for updating and installing Emacs packages.
|
|
|
|
;; 2. *Reach:* I want packages from sources other than ELPA (like github or
|
|
|
|
;; gitlab). Some plugins are out-of-date through official channels, have
|
|
|
|
;; changed hands, have a superior fork, or simply aren't available in ELPA
|
|
|
|
;; repos.
|
|
|
|
;; 3. *Performance:* The package management system isn't loaded until you use
|
|
|
|
;; the package management API. Not having to initialize package.el or quelpa
|
|
|
|
;; (and check that your packages are installed) every time you start up (or
|
|
|
|
;; load a package) speeds things up a great deal.
|
|
|
|
;; 4. *Separation of concerns:* It's more organized and reduces cognitive load
|
|
|
|
;; to separate configuring of packages and installing/updating them.
|
2017-02-06 00:13:24 -05:00
|
|
|
;;
|
2018-03-14 18:25:22 -04:00
|
|
|
;; You should be able to use package.el commands without any conflicts.
|
2017-02-06 00:13:24 -05:00
|
|
|
;;
|
|
|
|
;; See core/autoload/packages.el for more functions.
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(defvar doom-init-packages-p nil
|
|
|
|
"If non-nil, Doom's package management system has been initialized.")
|
|
|
|
|
2017-06-05 14:21:52 +02:00
|
|
|
(defvar doom-packages ()
|
2017-02-11 06:00:08 -05:00
|
|
|
"A list of enabled packages. Each element is a sublist, whose CAR is the
|
|
|
|
package's name as a symbol, and whose CDR is the plist supplied to its
|
2017-02-23 00:06:12 -05:00
|
|
|
`package!' declaration. Set by `doom-initialize-packages'.")
|
2017-02-11 06:00:08 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(defvar doom-core-packages '(straight use-package async)
|
2017-02-11 06:00:08 -05:00
|
|
|
"A list of packages that must be installed (and will be auto-installed if
|
|
|
|
missing) and shouldn't be deleted.")
|
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(defvar doom-core-package-sources
|
|
|
|
'((org-elpa :local-repo nil)
|
|
|
|
(melpa
|
|
|
|
:type git :host github
|
|
|
|
:repo "melpa/melpa"
|
|
|
|
:no-build t)
|
|
|
|
(gnu-elpa-mirror
|
|
|
|
:type git :host github
|
|
|
|
:repo "emacs-straight/gnu-elpa-mirror"
|
|
|
|
:no-build t)
|
|
|
|
(emacsmirror-mirror
|
|
|
|
:type git :host github
|
|
|
|
:repo "emacs-straight/emacsmirror-mirror"
|
|
|
|
:no-build t))
|
|
|
|
"A list of recipes for straight's recipe repos.")
|
|
|
|
|
2017-06-05 16:45:42 +02:00
|
|
|
(defvar doom-disabled-packages ()
|
2019-05-13 19:29:38 -04:00
|
|
|
"A list of packages that should be ignored by `def-package!' and `after!'.")
|
2017-06-05 16:45:42 +02:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Package managers
|
|
|
|
|
|
|
|
;; Ensure that, if we do need package.el, it is configured correctly. You really
|
|
|
|
;; shouldn't be using it, but it may be convenient for quick package testing.
|
2018-06-11 23:18:15 +02:00
|
|
|
(setq package--init-file-ensured t
|
2017-01-16 23:15:48 -05:00
|
|
|
package-enable-at-startup nil
|
2019-07-21 15:39:45 +02:00
|
|
|
package-user-dir doom-elpa-dir
|
|
|
|
package-gnupghome-dir (expand-file-name "gpg" doom-elpa-dir)
|
2017-02-11 00:46:42 -05:00
|
|
|
;; I omit Marmalade because its packages are manually submitted rather
|
|
|
|
;; than pulled, so packages are often out of date with upstream.
|
2019-05-12 22:09:52 -04:00
|
|
|
package-archives
|
2019-07-21 15:39:45 +02:00
|
|
|
(let ((proto (if gnutls-verify-error "http" "https")))
|
|
|
|
`(("gnu" . ,(concat proto "://elpa.gnu.org/packages/"))
|
|
|
|
("melpa" . ,(concat proto "://melpa.org/packages/"))
|
|
|
|
("org" . ,(concat proto "://orgmode.org/elpa/")))))
|
2019-05-12 22:09:52 -04:00
|
|
|
|
2019-07-02 23:13:01 +02:00
|
|
|
;; Don't save `package-selected-packages' to `custom-file'
|
2019-07-21 15:39:45 +02:00
|
|
|
(def-advice! doom--package-inhibit-custom-file-a (&optional value)
|
|
|
|
:override #'package--save-selected-packages
|
|
|
|
(if value (setq package-selected-packages value)))
|
2019-07-02 23:13:01 +02:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
;;; straight
|
|
|
|
(setq straight-cache-autoloads nil ; we already do this, and better.
|
|
|
|
;; Doom doesn't encourage you to modify packages in place. Disabling this
|
|
|
|
;; makes 'doom refresh' instant (once everything set up), which is much
|
|
|
|
;; nicer UX than the several seconds modification checks add.
|
|
|
|
straight-check-for-modifications nil
|
|
|
|
;; We do this ourselves, and a little more comprehensively.
|
|
|
|
straight-enable-package-integration nil
|
2019-07-22 02:36:49 +02:00
|
|
|
straight-enable-use-package-integration nil
|
2019-07-21 15:39:45 +02:00
|
|
|
;; Before switching to straight, `doom-local-dir' would average out at
|
|
|
|
;; around 100mb. Afterwards, at around 1gb. With shallow cloning, that is
|
|
|
|
;; reduced to ~400mb. This imposes an isuse with packages that require
|
|
|
|
;; their git history for certain things to work (like magit and org), but
|
|
|
|
;; we're prepared for that.
|
|
|
|
straight-vc-git-default-clone-depth 1
|
|
|
|
;; Straight's own emacsmirror mirro is a little smaller and faster.
|
|
|
|
straight-recipes-emacsmirror-use-mirror t
|
|
|
|
;; Prefix declarations are unneeded bulk added to our autoloads file. Best
|
|
|
|
;; we just don't have to deal with them at all.
|
|
|
|
autoload-compute-prefixes nil)
|
2019-05-12 22:09:52 -04:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
;; Straight is hardcoded to operate out of ~/.emacs.d/straight. Not on my watch!
|
|
|
|
(def-advice! doom--straight-use-local-dir-a (orig-fn &rest args)
|
|
|
|
:around #'straight--emacs-dir
|
|
|
|
(let ((user-emacs-directory doom-local-dir))
|
|
|
|
(apply orig-fn args)))
|
2018-05-14 15:57:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2019-05-12 22:09:52 -04:00
|
|
|
;;; Bootstrapper
|
2018-05-14 15:57:54 +02:00
|
|
|
|
2018-03-02 17:45:15 -05:00
|
|
|
(defun doom-initialize-packages (&optional force-p)
|
2019-07-21 15:39:45 +02:00
|
|
|
"Ensures that Doom's package system and straight.el are initialized.
|
2018-03-02 17:45:15 -05:00
|
|
|
|
2018-05-20 00:01:07 +02:00
|
|
|
If FORCE-P is non-nil, do it anyway.
|
2018-03-02 17:45:15 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
This ensure `doom-packages' is populated, if isn't aren't already. Use this
|
|
|
|
before any of straight's or Doom's package management's API to ensure all the
|
|
|
|
necessary package metadata is initialized and available for them."
|
|
|
|
(when (or force-p (not doom-init-packages-p))
|
|
|
|
(setq doom-init-packages-p t)
|
|
|
|
(straight--reset-caches)
|
|
|
|
(mapc #'straight-use-recipes doom-core-package-sources)
|
|
|
|
(straight-register-package
|
|
|
|
`(straight :type git :host github
|
|
|
|
:repo ,(format "%s/straight.el" straight-repository-user)
|
|
|
|
:files ("straight*.el")
|
|
|
|
:branch ,straight-repository-branch))
|
|
|
|
(mapc #'straight-use-package doom-core-packages)
|
|
|
|
(when noninteractive
|
|
|
|
(add-hook 'kill-emacs-hook #'straight--transaction-finalize))
|
|
|
|
(dolist (package (straight--directory-files (straight--build-dir)))
|
|
|
|
(add-to-list 'load-path (directory-file-name (straight--build-dir package)))))
|
|
|
|
(when (or force-p (not doom-packages))
|
2019-07-22 03:48:29 +02:00
|
|
|
;; On first install, the packages API will be unavailable
|
|
|
|
(unless (fboundp 'doom-package-list)
|
|
|
|
(load! "autoload/packages.el"))
|
2019-07-21 15:39:45 +02:00
|
|
|
(setq doom-disabled-packages nil
|
|
|
|
doom-packages (doom-package-list))
|
|
|
|
(cl-loop for (pkg . plist) in doom-packages
|
|
|
|
for ignored = (eval (plist-get plist :ignore) t)
|
|
|
|
for disabled = (eval (plist-get plist :disable) t)
|
|
|
|
if disabled
|
|
|
|
do (add-to-list 'doom-disabled-packages pkg)
|
|
|
|
else if (not ignored)
|
|
|
|
do (with-demoted-errors "Package error: %s"
|
|
|
|
(straight-register-package
|
|
|
|
(if-let (recipe (plist-get plist :recipe))
|
|
|
|
`(,pkg ,@recipe)
|
|
|
|
pkg))))))
|
2018-03-02 17:45:15 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(defun doom-ensure-straight ()
|
|
|
|
"Ensure `straight' is installed and was compiled with this version of Emacs."
|
|
|
|
(defvar bootstrap-version)
|
|
|
|
(let* ((straight-dir (expand-file-name "straight/" doom-local-dir))
|
|
|
|
(bootstrap-file (expand-file-name "repos/straight.el/straight.el" straight-dir))
|
|
|
|
(bootstrap-version 5)
|
|
|
|
;; Force straight to install into ~/.emacs.d/.local/straight instead of
|
|
|
|
;; ~/.emacs.d/straight by pretending `doom-local-dir' is our .emacs.d.
|
|
|
|
(user-emacs-directory doom-local-dir))
|
|
|
|
(cl-block 'straight
|
|
|
|
;; Straight will throw `emacs-version-changed' if it's loaded with a
|
|
|
|
;; version of Emacs that doesn't match the one it was compiled with.
|
|
|
|
;; Getting this error isn't very good UX...
|
|
|
|
(catch 'emacs-version-changed
|
|
|
|
(unless (require 'straight nil t)
|
|
|
|
(unless (file-exists-p bootstrap-file)
|
|
|
|
(with-current-buffer
|
|
|
|
(url-retrieve-synchronously
|
|
|
|
"https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
|
|
|
|
'silent 'inhibit-cookies)
|
|
|
|
(goto-char (point-max))
|
|
|
|
(eval-print-last-sexp)))
|
|
|
|
(load bootstrap-file nil 'nomessage))
|
|
|
|
(cl-return-from 'straight t))
|
|
|
|
;; ...so we transform it into a more graceful error message:
|
|
|
|
(with-temp-buffer
|
|
|
|
(insert-file-contents-literally (expand-file-name "build-cache.el" straight-dir))
|
|
|
|
(let ((_ (read (current-buffer)))
|
|
|
|
(last-emacs-version (read (current-buffer))))
|
|
|
|
(user-error "Your version of Emacs has changed (from %S to %S). You must rebuild your packages with 'doom rebuild'."
|
|
|
|
emacs-version last-emacs-version))))))
|
2017-02-11 06:52:38 -05:00
|
|
|
|
2017-02-06 00:13:24 -05:00
|
|
|
|
2017-02-11 00:46:42 -05:00
|
|
|
;;
|
2019-07-21 15:39:45 +02:00
|
|
|
;;; Module package macros
|
2017-01-16 23:15:48 -05:00
|
|
|
|
2019-07-21 15:39:45 +02:00
|
|
|
(cl-defmacro package! (name &rest plist &key built-in _recipe disable ignore _freeze)
|
2017-07-02 16:47:02 +02:00
|
|
|
"Declares a package and how to install it (if applicable).
|
|
|
|
|
|
|
|
This macro is declarative and does not load nor install packages. It is used to
|
|
|
|
populate `doom-packages' with metadata about the packages Doom needs to keep
|
|
|
|
track of.
|
|
|
|
|
2018-04-03 15:00:52 -04:00
|
|
|
Only use this macro in a module's packages.el file.
|
2017-02-04 21:07:54 -05:00
|
|
|
|
2017-02-11 00:46:42 -05:00
|
|
|
Accepts the following properties:
|
2017-02-03 20:10:40 -05:00
|
|
|
|
2018-03-26 16:44:24 -04:00
|
|
|
:recipe RECIPE
|
|
|
|
Takes a MELPA-style recipe (see `quelpa-recipe' in `quelpa' for an example);
|
|
|
|
for packages to be installed from external sources.
|
|
|
|
:disable BOOL
|
|
|
|
Do not install or update this package AND disable all of its `def-package!'
|
|
|
|
blocks.
|
|
|
|
:ignore FORM
|
2018-03-26 18:15:03 -04:00
|
|
|
Do not install this package.
|
2018-03-26 16:44:24 -04:00
|
|
|
:freeze FORM
|
2018-05-15 23:11:48 +02:00
|
|
|
Do not update this package if FORM is non-nil.
|
2019-03-06 00:26:33 -05:00
|
|
|
:built-in BOOL
|
2019-07-05 20:03:37 +02:00
|
|
|
Same as :ignore if the package is a built-in Emacs package. If set to
|
|
|
|
'prefer, will use built-in package if it is present.
|
2018-05-15 23:11:48 +02:00
|
|
|
|
|
|
|
Returns t if package is successfully registered, and nil if it was disabled
|
|
|
|
elsewhere."
|
2017-01-16 23:15:48 -05:00
|
|
|
(declare (indent defun))
|
2019-03-06 00:26:33 -05:00
|
|
|
(let ((old-plist (cdr (assq name doom-packages))))
|
|
|
|
(let ((module-list (plist-get old-plist :modules))
|
|
|
|
(module (or doom--current-module
|
2019-07-21 15:39:45 +02:00
|
|
|
(let ((file (file!)))
|
2019-03-06 00:26:33 -05:00
|
|
|
(cond ((file-in-directory-p file doom-private-dir)
|
|
|
|
(list :private))
|
|
|
|
((file-in-directory-p file doom-core-dir)
|
|
|
|
(list :core))
|
|
|
|
((doom-module-from-path file)))))))
|
|
|
|
(unless (member module module-list)
|
|
|
|
(setq module-list (append module-list (list module) nil)
|
|
|
|
plist (plist-put plist :modules module-list))))
|
2019-06-11 08:01:42 +02:00
|
|
|
(when built-in
|
2019-07-05 22:28:55 +02:00
|
|
|
(doom-log "Ignoring built-in package %S" name)
|
2019-07-05 23:07:05 +02:00
|
|
|
(when (equal built-in '(quote prefer))
|
2019-07-21 15:39:45 +02:00
|
|
|
(setq built-in `(locate-library ,(symbol-name name) nil doom--initial-load-path))))
|
2019-07-05 22:28:55 +02:00
|
|
|
(setq plist (plist-put plist :ignore (or built-in ignore)))
|
2019-03-06 00:26:33 -05:00
|
|
|
(while plist
|
|
|
|
(unless (null (cadr plist))
|
|
|
|
(setq old-plist (plist-put old-plist (car plist) (cadr plist))))
|
|
|
|
(pop plist)
|
|
|
|
(pop plist))
|
|
|
|
(setq plist old-plist)
|
2019-07-21 15:39:45 +02:00
|
|
|
;; TODO Add `straight-use-package-pre-build-function' support
|
2018-06-24 19:58:25 +02:00
|
|
|
(macroexp-progn
|
2019-07-21 15:39:45 +02:00
|
|
|
(append `((setf (alist-get ',name doom-packages) ',plist))
|
2019-05-02 21:54:47 -04:00
|
|
|
(when disable
|
2019-07-21 15:39:45 +02:00
|
|
|
`((doom-log "Disabling package %S" ',name)
|
|
|
|
(add-to-list 'doom-disabled-packages ',name nil 'eq)
|
2019-05-02 21:54:47 -04:00
|
|
|
nil))))))
|
2017-01-28 02:02:16 -05:00
|
|
|
|
2018-03-26 02:58:22 -04:00
|
|
|
(defmacro disable-packages! (&rest packages)
|
:boom: revise advice naming convention (1/2)
This is first of three big naming convention updates that have been a
long time coming. With 2.1 on the horizon, all the breaking updates will
batched together in preparation for the long haul.
In this commit, we do away with the asterix to communicate that a
function is an advice function, and we replace it with the '-a' suffix.
e.g.
doom*shut-up -> doom-shut-up-a
doom*recenter -> doom-recenter-a
+evil*static-reindent -> +evil--static-reindent-a
The rationale behind this change is:
1. Elisp's own formatting/indenting tools would occasionally struggle
with | and * (particularly pp and cl-prettyprint). They have no
problem with / and :, fortunately.
2. External syntax highlighters (like pygmentize, discord markdown or
github markdown) struggle with it, sometimes refusing to highlight
code beyond these symbols.
3. * and | are less expressive than - and -- in communicating the
intended visibility, versatility and stability of a function.
4. It complicated the regexps we must use to search for them.
5. They were arbitrary and over-complicated to begin with, decided
on haphazardly way back when Doom was simply "my private config".
Anyhow, like how predicate functions have the -p suffix, we'll adopt the
-a suffix for advice functions, -h for hook functions and -fn for
variable functions.
Other noteable changes:
- Replaces advice-{add,remove}! macro with new def-advice!
macro. The old pair weren't as useful. The new def-advice! saves on a
lot of space.
- Removed "stage" assertions to make sure you were using the right
macros in the right place. Turned out to not be necessary, we'll
employ better checks later.
2019-07-18 15:42:52 +02:00
|
|
|
"A convenience macro for disabling packages in bulk.
|
|
|
|
Only use this macro in a module's (or your private) packages.el file."
|
2019-01-02 13:17:26 -05:00
|
|
|
(macroexp-progn
|
2019-07-21 15:39:45 +02:00
|
|
|
(cl-loop for p in packages
|
|
|
|
collect `(package! ,p :disable t))))
|
2018-03-26 02:58:22 -04:00
|
|
|
|
2017-01-16 23:15:48 -05:00
|
|
|
(provide 'core-packages)
|
|
|
|
;;; core-packages.el ends here
|