Refactor doom-initialize-packages & package API
- Packages are initialized once, when package.el is first loaded, and must be updated manually via doom/reload-packages. - Package->module association is now stored in the package's PLIST under :modules. This is an internal property and cannot be explicitly set through `package!' - Add doom-package-list function - Rename doom-get-packages to doom-find-packages - Updated doom-find-packages' docstring - Added the :core filter to doom-find-packages - Simplified doom-initialize-packages - doom/reload calls doom/reload-packages if necessary. - Fix redundant properties in doom-packages - Remove tracking of after!, def-package! and def-package-hook! blocks. Replaced with doom-package-list being able to see all packages, even in disabled modules. - Add :built-in property to package! for dummy packages. This is important so that doom/describe-package can see built-in packages.
This commit is contained in:
parent
8bfa5a30fd
commit
a443d9ab07
8 changed files with 207 additions and 182 deletions
|
@ -32,5 +32,7 @@ init.el and config.el. Then runs `doom-reload-hook'."
|
|||
(doom-initialize))
|
||||
(with-demoted-errors "PRIVATE CONFIG ERROR: %s"
|
||||
(doom-initialize-modules 'force))
|
||||
(when (bound-and-true-p doom-packages)
|
||||
(doom/reload-packages))
|
||||
(run-hook-wrapped 'doom-reload-hook #'doom-try-run-hook)
|
||||
(message "Finished!"))
|
||||
|
|
|
@ -61,7 +61,7 @@ ready to be pasted in a bug report on github."
|
|||
"n/a")
|
||||
(or (ignore-errors
|
||||
(require 'use-package)
|
||||
(cl-loop for (name . plist) in (doom-get-packages :private t)
|
||||
(cl-loop for (name . plist) in (doom-find-packages :private t)
|
||||
if (use-package-plist-delete (copy-sequence plist) :private)
|
||||
collect (format "%s" (cons name it))
|
||||
else
|
||||
|
|
|
@ -97,7 +97,6 @@ list of the package."
|
|||
"Return t if a package named NAME (a symbol) has a new backend than what it
|
||||
was installed with. Returns nil otherwise, or if package isn't installed."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(and (package-installed-p name)
|
||||
(let* ((plist (cdr (assq name doom-packages)))
|
||||
(old-backend (doom-package-backend name 'noerror))
|
||||
|
@ -109,7 +108,6 @@ was installed with. Returns nil otherwise, or if package isn't installed."
|
|||
"Return t if a package named NAME (a symbol) has a different recipe than it
|
||||
was installed with."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(and (package-installed-p name)
|
||||
(when-let* ((quelpa-recipe (assq name quelpa-cache))
|
||||
(doom-recipe (assq name doom-packages)))
|
||||
|
@ -117,15 +115,16 @@ was installed with."
|
|||
(cdr (plist-get (cdr doom-recipe) :recipe)))))))
|
||||
|
||||
;;;###autoload
|
||||
(cl-defun doom-get-packages (&key (installed 'any)
|
||||
(private 'any)
|
||||
(disabled 'any)
|
||||
(pinned 'any)
|
||||
(ignored 'any)
|
||||
(sort t)
|
||||
changed
|
||||
backend
|
||||
deps)
|
||||
(cl-defun doom-find-packages (&key (installed 'any)
|
||||
(private 'any)
|
||||
(disabled 'any)
|
||||
(pinned 'any)
|
||||
(ignored 'any)
|
||||
(core 'any)
|
||||
sort
|
||||
changed
|
||||
backend
|
||||
deps)
|
||||
"Retrieves a list of primary packages (i.e. non-dependencies). Each element is
|
||||
a cons cell, whose car is the package symbol and whose cdr is the quelpa recipe
|
||||
(if any).
|
||||
|
@ -133,76 +132,134 @@ a cons cell, whose car is the package symbol and whose cdr is the quelpa recipe
|
|||
You can build a filtering criteria using one or more of the following
|
||||
properties:
|
||||
|
||||
:backend BACKEND
|
||||
Can be 'quelpa, 'elpa or 'emacs
|
||||
:installed BOOL
|
||||
Only return installed packages (t) or uninstalled packages (nil)
|
||||
:private BOOL
|
||||
Only return private packages (t) or non-private packages (nil)
|
||||
:disabled BOOL
|
||||
Only return packages that are disabled (t) or otherwise (nil)
|
||||
:ignored BOOL
|
||||
Only return packages that are ignored (t) or otherwise (nil)
|
||||
:backend 'quelpa|'elpa|'emacs|'any
|
||||
Include packages installed through 'quelpa, 'elpa or 'emacs. 'any is the
|
||||
wildcard.
|
||||
:installed BOOL|'any
|
||||
t = only include installed packages
|
||||
nil = exclude installed packages
|
||||
:private BOOL|'any
|
||||
t = only include user-installed packages
|
||||
nil = exclude user-installed packages
|
||||
:core BOOL|'any
|
||||
t = only include Doom core packages
|
||||
nil = exclude Doom core packages
|
||||
:disabled BOOL|'any
|
||||
t = only include disabled packages
|
||||
nil = exclude disabled packages
|
||||
:ignored BOOL|'any
|
||||
t = only include ignored packages
|
||||
nil = exclude ignored packages
|
||||
:pinned BOOL|ARCHIVE
|
||||
Only return packages that are pinned (t), not pinned (nil) or pinned to a
|
||||
specific archive (stringp)
|
||||
:deps BOOL
|
||||
Includes the package's dependencies (t).
|
||||
Includes the package's dependencies (t) or not (nil).
|
||||
|
||||
The resulting list is sorted unless :sort nil is passed to this function.
|
||||
|
||||
Warning: this function is expensive, as it re-evaluates your all packages.el
|
||||
files."
|
||||
(doom-initialize-packages)
|
||||
(cl-remove-duplicates
|
||||
(cl-loop with packages = (append (mapcar #'list doom-core-packages)
|
||||
doom-packages)
|
||||
for (sym . plist)
|
||||
in (if sort
|
||||
(cl-sort (copy-sequence packages) #'string-lessp :key #'car)
|
||||
packages)
|
||||
if (and (or (not backend)
|
||||
(eq (doom-package-backend sym t) backend))
|
||||
(or (eq ignored 'any)
|
||||
(let* ((form (plist-get plist :ignore))
|
||||
(value (eval form)))
|
||||
(if ignored value (not value))))
|
||||
(or (eq disabled 'any)
|
||||
(if disabled
|
||||
(plist-get plist :disable)
|
||||
(not (plist-get plist :disable))))
|
||||
(or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p sym)
|
||||
(not (doom-package-installed-p sym))))
|
||||
(or (eq private 'any)
|
||||
(if private
|
||||
(plist-get plist :private)
|
||||
(not (plist-get plist :private))))
|
||||
(or (eq pinned 'any)
|
||||
(cond ((eq pinned 't)
|
||||
(plist-get plist :pin))
|
||||
((null pinned)
|
||||
(not (plist-get plist :pin)))
|
||||
((equal (plist-get plist :pin) pinned)))))
|
||||
collect (cons sym plist)
|
||||
and if (and deps (not (package-built-in-p sym)))
|
||||
nconc
|
||||
(cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror)
|
||||
if (or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p pkg)
|
||||
(not (doom-package-installed-p pkg))))
|
||||
collect (cons pkg (cdr (assq pkg doom-packages)))))
|
||||
:key #'car))
|
||||
(cl-loop with packages = doom-packages
|
||||
for (sym . plist)
|
||||
in (if sort
|
||||
(cl-sort (copy-sequence doom-packages) #'string-lessp :key #'car)
|
||||
packages)
|
||||
if (and (or (not backend)
|
||||
(eq (doom-package-backend sym t) backend))
|
||||
(or (eq ignored 'any)
|
||||
(let* ((form (plist-get plist :ignore))
|
||||
(value (eval form)))
|
||||
(if ignored value (not value))))
|
||||
(or (eq disabled 'any)
|
||||
(if disabled
|
||||
(plist-get plist :disable)
|
||||
(not (plist-get plist :disable))))
|
||||
(or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p sym)
|
||||
(not (doom-package-installed-p sym))))
|
||||
(or (eq private 'any)
|
||||
(let ((modules (plist-get plist :modules)))
|
||||
(if private
|
||||
(assq :private modules)
|
||||
(not (assq :private modules)))))
|
||||
(or (eq core 'any)
|
||||
(let ((modules (plist-get plist :modules)))
|
||||
(if core
|
||||
(assq :core modules)
|
||||
(not (assq :core modules)))))
|
||||
(or (eq pinned 'any)
|
||||
(cond ((eq pinned 't)
|
||||
(plist-get plist :pin))
|
||||
((null pinned)
|
||||
(not (plist-get plist :pin)))
|
||||
((equal (plist-get plist :pin) pinned)))))
|
||||
collect (cons sym plist)
|
||||
and if (and deps (not (package-built-in-p sym)))
|
||||
nconc
|
||||
(cl-loop for pkg in (doom-get-dependencies-for sym 'recursive 'noerror)
|
||||
if (or (eq installed 'any)
|
||||
(if installed
|
||||
(doom-package-installed-p pkg)
|
||||
(not (doom-package-installed-p pkg))))
|
||||
collect (cons pkg (cdr (assq pkg doom-packages))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-package-list (&optional all-p)
|
||||
"Retrieve a list of explicitly declared packages from enabled modules.
|
||||
|
||||
This excludes core packages listed in `doom-core-packages'.
|
||||
|
||||
If ALL-P, gather packages across all modules, including disabled ones."
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(let ((noninteractive t)
|
||||
(doom--stage 'packages)
|
||||
(doom-modules (doom-modules))
|
||||
doom-packages
|
||||
doom-disabled-packages
|
||||
package-pinned-packages)
|
||||
(cl-letf ((load-fn
|
||||
(lambda (file &optional noerror)
|
||||
(condition-case e
|
||||
(if all-p
|
||||
(setq doom-packages
|
||||
(append (let (doom-packages)
|
||||
(load file noerror t t)
|
||||
doom-packages)
|
||||
doom-packages))
|
||||
(load file noerror t t))
|
||||
((debug error)
|
||||
(signal 'doom-package-error
|
||||
(list (or (doom-module-from-path file)
|
||||
'(:private . packages))
|
||||
e)))))))
|
||||
(funcall load-fn (expand-file-name "packages.el" doom-core-dir))
|
||||
(let ((private-packages (expand-file-name "packages.el" doom-private-dir)))
|
||||
;; We load the private packages file twice to ensure disabled packages
|
||||
;; are seen ASAP, and a second time to ensure privately overridden
|
||||
;; packages are properly overwritten.
|
||||
(funcall load-fn private-packages t)
|
||||
(if all-p
|
||||
(mapc load-fn (doom-files-in doom-modules-dir
|
||||
:depth 2
|
||||
:full t
|
||||
:match "/packages\\.el$"))
|
||||
(cl-loop for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
for doom--current-module = key
|
||||
do (funcall load-fn path t)))
|
||||
(funcall load-fn private-packages t))
|
||||
(append (cl-loop for package in doom-core-packages
|
||||
collect (list package :modules '((:core internal))))
|
||||
(nreverse doom-packages))))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-package-alist ()
|
||||
"Returns a list of all desired packages, their dependencies and their desc
|
||||
objects, in the order of their `package! blocks.'"
|
||||
(doom-initialize-packages)
|
||||
(cl-remove-duplicates
|
||||
(cl-loop for name in (append doom-core-packages (mapcar #'car doom-packages))
|
||||
(cl-loop for name in (mapcar #'car doom-packages)
|
||||
if (assq name package-alist)
|
||||
nconc (cl-loop for dep in (package--get-deps name)
|
||||
if (assq dep package-alist)
|
||||
|
@ -245,7 +302,6 @@ containing (PACKAGE-SYMBOL OLD-VERSION-LIST NEW-VERSION-LIST).
|
|||
If INCLUDE-FROZEN-P is non-nil, check frozen packages as well.
|
||||
|
||||
Used by `doom-packages-update'."
|
||||
(doom-initialize-packages t)
|
||||
(doom-refresh-packages-maybe doom-debug-mode)
|
||||
(let-alist
|
||||
(seq-group-by
|
||||
|
@ -295,7 +351,7 @@ depended on.
|
|||
|
||||
Used by `doom-packages-autoremove'."
|
||||
(let ((package-selected-packages
|
||||
(mapcar #'car (doom-get-packages :ignored nil :disabled nil))))
|
||||
(mapcar #'car (doom-find-packages :ignored nil :disabled nil))))
|
||||
(append (package--removable-packages)
|
||||
(cl-loop for pkg in package-selected-packages
|
||||
if (and (doom-package-different-backend-p pkg)
|
||||
|
@ -303,22 +359,17 @@ Used by `doom-packages-autoremove'."
|
|||
collect pkg))))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom-get-missing-packages (&optional include-ignored-p)
|
||||
(defun doom-get-missing-packages ()
|
||||
"Return a list of requested packages that aren't installed or built-in, but
|
||||
are enabled (with a `package!' directive). Each element is a list whose CAR is
|
||||
the package symbol, and whose CDR is a plist taken from that package's
|
||||
`package!' declaration.
|
||||
|
||||
If INCLUDE-IGNORED-P is non-nil, includes missing packages that are ignored,
|
||||
i.e. they have an :ignore property.
|
||||
|
||||
Used by `doom-packages-install'."
|
||||
(doom-initialize-packages)
|
||||
(cl-loop for (name . plist)
|
||||
in (doom-get-packages :ignored (if include-ignored-p 'any)
|
||||
:disabled nil
|
||||
:deps t
|
||||
:sort nil)
|
||||
in (doom-find-packages :ignored nil
|
||||
:disabled nil
|
||||
:deps t)
|
||||
if (and (or (plist-get plist :pin)
|
||||
(not (package-built-in-p name)))
|
||||
(or (not (doom-package-installed-p name))
|
||||
|
@ -343,7 +394,6 @@ Used by `doom-packages-install'."
|
|||
"Installs package NAME with optional quelpa RECIPE (see `quelpa-recipe' for an
|
||||
example; the package name can be omitted)."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(when (and (package-installed-p name)
|
||||
(not (package-built-in-p name)))
|
||||
(if (or (doom-package-different-backend-p name)
|
||||
|
@ -371,7 +421,6 @@ example; the package name can be omitted)."
|
|||
"Updates package NAME (a symbol) if it is out of date, using quelpa or
|
||||
package.el as appropriate."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(unless (package-installed-p name)
|
||||
(error "%s isn't installed" name))
|
||||
(when (doom-package-different-backend-p name)
|
||||
|
@ -402,7 +451,6 @@ package.el as appropriate."
|
|||
(defun doom-delete-package (name &optional force-p)
|
||||
"Uninstalls package NAME if it exists, and clears it from `quelpa-cache'."
|
||||
(cl-check-type name symbol)
|
||||
(doom-initialize-packages)
|
||||
(unless (package-installed-p name)
|
||||
(user-error "%s isn't installed" name))
|
||||
(let ((inhibit-message (not doom-debug-mode))
|
||||
|
@ -420,6 +468,14 @@ package.el as appropriate."
|
|||
;;
|
||||
;; Interactive commands
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/reload-packages ()
|
||||
"Reload `doom-packages', `package' and `quelpa'."
|
||||
(interactive)
|
||||
(message "Reloading packages")
|
||||
(doom-initialize-packages t)
|
||||
(message "Reloading packages...DONE"))
|
||||
|
||||
;;;###autoload
|
||||
(defun doom/update-package (pkg)
|
||||
"Prompts the user with a list of outdated packages and updates the selected
|
||||
|
@ -437,7 +493,6 @@ calls."
|
|||
(unless name
|
||||
(user-error "'%s' is already up-to-date" selection))
|
||||
(list (assq name packages))))
|
||||
(doom-initialize-packages)
|
||||
(cl-destructuring-bind (package old-version new-version) pkg
|
||||
(if-let* ((desc (doom-package-outdated-p package)))
|
||||
(let ((old-v-str (package-version-join old-version))
|
||||
|
@ -457,7 +512,6 @@ calls."
|
|||
;;;###autoload
|
||||
(defun doom*package-delete (desc &rest _)
|
||||
"Update `quelpa-cache' upon a successful `package-delete'."
|
||||
(doom-initialize-packages)
|
||||
(let ((name (package-desc-name desc)))
|
||||
(unless (package-installed-p name)
|
||||
(when-let* ((spec (assq name quelpa-cache)))
|
||||
|
|
|
@ -318,7 +318,7 @@ modified."
|
|||
(prin1 `(setq load-path ',load-path
|
||||
auto-mode-alist ',auto-mode-alist
|
||||
Info-directory-list ',Info-directory-list
|
||||
doom-disabled-packages ',doom-disabled-packages
|
||||
doom-disabled-packages ',(mapcar #'car (doom-find-packages :disabled t))
|
||||
package-activated-list ',package-activated-list)
|
||||
(current-buffer)))
|
||||
|
||||
|
@ -352,10 +352,10 @@ This should be run whenever your `doom!' block or update your packages."
|
|||
(with-temp-file doom-package-autoload-file
|
||||
(doom--generate-header 'doom-reload-package-autoloads)
|
||||
(save-excursion
|
||||
;; Cache the important and expensive-to-initialize state here.
|
||||
;; Cache important and expensive-to-initialize state here.
|
||||
(doom--generate-var-cache)
|
||||
(print! (green "✓ Cached package state"))
|
||||
;; Loop through packages and concatenate all their autoloads files.
|
||||
;; Concatenate the autoloads of all installed packages.
|
||||
(doom--generate-package-autoloads)
|
||||
(print! (green "✓ Package autoloads included")))
|
||||
;; Remove `load-path' and `auto-mode-alist' modifications (most of them,
|
||||
|
|
|
@ -224,9 +224,7 @@ BODY is evaluated once TARGETS are loaded. TARGETS can either be:
|
|||
#'progn
|
||||
#'with-no-warnings)
|
||||
(if (symbolp targets)
|
||||
`(progn
|
||||
(doom-module-register-config ',targets ,(FILE!))
|
||||
(with-eval-after-load ',targets ,@body))
|
||||
`(with-eval-after-load ',targets ,@body)
|
||||
(pcase (car-safe targets)
|
||||
((or :or :any)
|
||||
(macroexp-progn
|
||||
|
|
|
@ -188,15 +188,6 @@ non-nil, return paths of possible modules, activated or otherwise."
|
|||
collect (plist-get plist :path)))
|
||||
(list doom-private-dir)))
|
||||
|
||||
(defun doom-module-register-config (package file &optional append)
|
||||
"TODO"
|
||||
(let ((files (get package 'doom-files)))
|
||||
(unless (member file files)
|
||||
(if append
|
||||
(setq files (append files (list file)))
|
||||
(push file files))
|
||||
(put package 'doom-files files))))
|
||||
|
||||
(defun doom-modules (&optional refresh-p)
|
||||
"Minimally initialize `doom-modules' (a hash table) and return it."
|
||||
(or (unless refresh-p doom-modules)
|
||||
|
@ -372,9 +363,7 @@ package is disabled."
|
|||
;; package errors, so we preform this check at compile time:
|
||||
(and (bound-and-true-p byte-compile-current-file)
|
||||
(not (locate-library (symbol-name name)))))
|
||||
`(progn
|
||||
(doom-module-register-config ',name ,(FILE!) t)
|
||||
(use-package ,name ,@plist))))
|
||||
`(use-package ,name ,@plist)))
|
||||
|
||||
(defmacro def-package-hook! (package when &rest body)
|
||||
"Reconfigures a package's `def-package!' block.
|
||||
|
@ -396,7 +385,6 @@ to have them return non-nil (or exploit that to overwrite Doom's config)."
|
|||
(error "'%s' isn't a valid hook for def-package-hook!" when))
|
||||
`(progn
|
||||
(setq use-package-inject-hooks t)
|
||||
(doom-module-register-config ',package ,(FILE!))
|
||||
(add-hook!
|
||||
',(intern (format "use-package--%s--%s-hook"
|
||||
package
|
||||
|
|
|
@ -87,52 +87,27 @@ If FORCE-P is 'internal, only (re)populate `doom-packages'.
|
|||
Use this before any of package.el, quelpa or Doom's package management's API to
|
||||
ensure all the necessary package metadata is initialized and available for
|
||||
them."
|
||||
(with-temp-buffer ; prevent buffer-local settings from propagating
|
||||
(let ((load-prefer-newer t)) ; reduce stale code issues
|
||||
;; package.el and quelpa handle themselves if their state changes during
|
||||
;; the current session, but if you change an packages.el file in a module,
|
||||
;; there's no non-trivial way to detect that, so we give you a way to
|
||||
;; reload only doom-packages (by passing 'internal as FORCE-P).
|
||||
(unless (eq force-p 'internal)
|
||||
;; `package-alist'
|
||||
(when (or force-p (not (bound-and-true-p package-alist)))
|
||||
(doom-ensure-packages-initialized 'force)
|
||||
(setq load-path (cl-remove-if-not #'file-directory-p load-path)))
|
||||
;; `quelpa-cache'
|
||||
(when (or force-p (not (bound-and-true-p quelpa-cache)))
|
||||
;; ensure un-byte-compiled version of quelpa is loaded
|
||||
(unless (featurep 'quelpa)
|
||||
(load (locate-library "quelpa.el") nil t t))
|
||||
(setq quelpa-initialized-p nil)
|
||||
(or (quelpa-setup-p)
|
||||
(error "Could not initialize quelpa"))))
|
||||
;; `doom-packages'
|
||||
(when (or force-p (not doom-packages))
|
||||
(cl-flet
|
||||
((_load
|
||||
(lambda (file &optional noerror)
|
||||
(condition-case e
|
||||
(load file noerror t t)
|
||||
((debug error)
|
||||
(signal 'doom-package-error
|
||||
(list (or (doom-module-from-path file)
|
||||
'(:private . packages))
|
||||
e)))))))
|
||||
(let ((doom-modules (doom-modules))
|
||||
(doom--stage 'packages)
|
||||
(noninteractive t))
|
||||
(setq doom-packages nil)
|
||||
(_load (expand-file-name "packages.el" doom-core-dir))
|
||||
;; We load the private packages file twice to ensure disabled
|
||||
;; packages are seen ASAP, and a second time to ensure privately
|
||||
;; overridden packages are properly overwritten.
|
||||
(let ((private-packages (expand-file-name "packages.el" doom-private-dir)))
|
||||
(_load private-packages t)
|
||||
(cl-loop for key being the hash-keys of doom-modules
|
||||
for path = (doom-module-path (car key) (cdr key) "packages.el")
|
||||
do (let ((doom--current-module key)) (_load path t)))
|
||||
(_load private-packages t)
|
||||
(setq doom-packages (reverse doom-packages)))))))))
|
||||
(let ((load-prefer-newer t)) ; reduce stale code issues
|
||||
;; package.el and quelpa handle themselves if their state changes during the
|
||||
;; current session, but if you change an packages.el file in a module,
|
||||
;; there's no non-trivial way to detect that, so to reload only
|
||||
;; doom-packages pass 'internal as FORCE-P or use `doom/reload-packages'.
|
||||
(unless (eq force-p 'internal)
|
||||
;; `package-alist'
|
||||
(when (or force-p (not (bound-and-true-p package-alist)))
|
||||
(doom-ensure-packages-initialized 'force)
|
||||
(setq load-path (cl-delete-if-not #'file-directory-p load-path)))
|
||||
;; `quelpa-cache'
|
||||
(when (or force-p (not (bound-and-true-p quelpa-cache)))
|
||||
;; ensure un-byte-compiled version of quelpa is loaded
|
||||
(unless (featurep 'quelpa)
|
||||
(load (locate-library "quelpa.el") nil t t))
|
||||
(setq quelpa-initialized-p nil)
|
||||
(or (quelpa-setup-p)
|
||||
(error "Could not initialize quelpa"))))
|
||||
;; `doom-packages'
|
||||
(when (or force-p (not doom-packages))
|
||||
(setq doom-packages (doom-package-list)))))
|
||||
|
||||
|
||||
;;
|
||||
|
@ -169,7 +144,7 @@ them."
|
|||
;;
|
||||
;; Module package macros
|
||||
|
||||
(cl-defmacro package! (name &rest plist &key recipe pin disable _ignore _freeze)
|
||||
(cl-defmacro package! (name &rest plist &key built-in recipe pin disable _ignore _freeze)
|
||||
"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
|
||||
|
@ -193,41 +168,49 @@ Accepts the following properties:
|
|||
Do not install this package.
|
||||
:freeze FORM
|
||||
Do not update this package if FORM is non-nil.
|
||||
:built-in BOOL
|
||||
Same as :ignore if the package is a built-in Emacs package.
|
||||
|
||||
Returns t if package is successfully registered, and nil if it was disabled
|
||||
elsewhere."
|
||||
(declare (indent defun))
|
||||
(doom--assert-stage-p 'packages #'package!)
|
||||
(let ((plist (append plist (cdr (assq name doom-packages)))))
|
||||
(let ((old-plist (cdr (assq name doom-packages))))
|
||||
(when recipe
|
||||
(when (cl-evenp (length recipe))
|
||||
(setq plist (plist-put plist :recipe (cons name recipe))))
|
||||
(setq pin nil
|
||||
plist (plist-put plist :pin nil)))
|
||||
(when (file-in-directory-p (FILE!) doom-private-dir)
|
||||
(setq plist (plist-put plist :private t)))
|
||||
(let (newplist)
|
||||
(while plist
|
||||
(unless (null (cadr plist))
|
||||
(push (cadr plist) newplist)
|
||||
(push (car plist) newplist))
|
||||
(pop plist)
|
||||
(pop plist))
|
||||
(setq plist newplist))
|
||||
(let ((module-list (plist-get old-plist :modules))
|
||||
(module (or doom--current-module
|
||||
(let ((file (FILE!)))
|
||||
(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)))))))
|
||||
(doom-log "Registered package '%s'%s"
|
||||
name (if recipe (format " with recipe %s" recipe) ""))
|
||||
(unless (member module module-list)
|
||||
(setq module-list (append module-list (list module) nil)
|
||||
plist (plist-put plist :modules module-list))))
|
||||
(when (and built-in (locate-library (symbol-name name) nil doom-site-load-path))
|
||||
(doom-log "Ignoring built-in package '%s'" name)
|
||||
(setq plist (plist-put plist :ignore t)))
|
||||
(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)
|
||||
(macroexp-progn
|
||||
(append (if disable `((add-to-list 'doom-disabled-packages ',name nil #'eq)))
|
||||
(if pin `((setf (alist-get ',name package-pinned-packages) ,pin)))
|
||||
`((let ((doom--current-module
|
||||
(or doom--current-module
|
||||
(let ((file (FILE!)))
|
||||
(cond ((file-in-directory-p file doom-private-dir)
|
||||
(cons :private (intern (file-name-base file))))
|
||||
((file-in-directory-p file doom-core-dir)
|
||||
(cons :core nil))))))
|
||||
(modules (get ',name 'doom-module)))
|
||||
(cl-pushnew doom--current-module modules)
|
||||
(put ',name 'doom-module modules))
|
||||
(setf (alist-get ',name doom-packages) ',plist)
|
||||
(append (when disable
|
||||
(doom-log "Disabling package '%s'" name)
|
||||
`((add-to-list 'doom-disabled-packages ',name nil 'eq)))
|
||||
(when pin
|
||||
(doom-log "Pinning package '%s' to '%s'" name pin)
|
||||
`((setf (alist-get ',name package-pinned-packages) ,pin)))
|
||||
`((setf (alist-get ',name doom-packages) ',plist)
|
||||
(not (memq ',name doom-disabled-packages)))))))
|
||||
|
||||
(defmacro packages! (&rest packages)
|
||||
|
|
|
@ -55,8 +55,8 @@
|
|||
(doom-missing-dummy)
|
||||
(doom-noquelpa-dummy)
|
||||
(doom-disabled-dummy :disable t)
|
||||
(doom-private-dummy :private t)
|
||||
(doom-disabled-private-dummy :private t :disable t)
|
||||
(doom-private-dummy :modules ((:private)))
|
||||
(doom-disabled-private-dummy :modules ((:private)) :disable t)
|
||||
(doom-quelpa-dummy :recipe (doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")))
|
||||
quelpa-cache
|
||||
'((doom-quelpa-dummy :fetcher github :repo "hlissner/does-not-exist")
|
||||
|
@ -95,31 +95,31 @@
|
|||
(spy-on #'doom-package-installed-p :and-call-fake #'package-installed-p))
|
||||
|
||||
(it "returns all packages"
|
||||
(expect (mapcar #'car (doom-get-packages))
|
||||
(expect (mapcar #'car (doom-find-packages))
|
||||
:to-have-same-items-as
|
||||
(mapcar #'car doom-packages)))
|
||||
(it "returns only disabled packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only non-disabled packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-missing-dummy doom-noquelpa-dummy doom-private-dummy)))
|
||||
(it "returns only installed packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil :installed t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed t))
|
||||
:to-have-same-items-as
|
||||
'(doom-dummy doom-uptodate-dummy doom-quelpa-dummy doom-noquelpa-dummy)))
|
||||
(it "returns only non-installed packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled nil :installed nil))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled nil :installed nil))
|
||||
:to-have-same-items-as
|
||||
'(doom-missing-dummy doom-private-dummy)))
|
||||
(it "returns only private packages"
|
||||
(expect (mapcar #'car (doom-get-packages :private t))
|
||||
(expect (mapcar #'car (doom-find-packages :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-private-dummy doom-disabled-private-dummy)))
|
||||
(it "returns only disabled and private packages"
|
||||
(expect (mapcar #'car (doom-get-packages :disabled t :private t))
|
||||
(expect (mapcar #'car (doom-find-packages :disabled t :private t))
|
||||
:to-have-same-items-as
|
||||
'(doom-disabled-private-dummy))))
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue