2017-06-08 11:47:56 +02:00
|
|
|
;;; core/autoload/packages.el -*- lexical-binding: t; -*-
|
2017-02-02 19:15:58 -05:00
|
|
|
|
2019-06-11 08:01:42 +02:00
|
|
|
;;
|
|
|
|
;;; Package metadata
|
|
|
|
|
2017-02-03 07:58:16 -05:00
|
|
|
;;;###autoload
|
2019-07-21 15:39:45 +02:00
|
|
|
(defun doom-package-get (package &optional prop nil-value)
|
2019-06-11 08:01:42 +02:00
|
|
|
"Returns PACKAGE's `package!' recipe from `doom-packages'."
|
2019-07-21 15:39:45 +02:00
|
|
|
(let ((plist (cdr (assq package doom-packages))))
|
|
|
|
(if prop
|
|
|
|
(if (plist-member plist prop)
|
|
|
|
(plist-get plist prop)
|
|
|
|
nil-value)
|
|
|
|
plist)))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-recipe (package &optional prop nil-value)
|
|
|
|
"Returns the `straight' recipe PACKAGE was registered with."
|
|
|
|
(let ((plist (gethash (symbol-name package) straight--recipe-cache)))
|
|
|
|
(if prop
|
|
|
|
(if (plist-member plist prop)
|
|
|
|
(plist-get plist prop)
|
|
|
|
nil-value)
|
|
|
|
plist)))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-build-recipe (package &optional prop nil-value)
|
|
|
|
"Returns the `straight' recipe PACKAGE was installed with."
|
|
|
|
(let ((plist (nth 2 (gethash (symbol-name package) straight--build-cache))))
|
|
|
|
(if prop
|
|
|
|
(if (plist-member plist prop)
|
|
|
|
(plist-get plist prop)
|
|
|
|
nil-value)
|
|
|
|
plist)))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-build-time (package)
|
2019-06-11 08:01:42 +02:00
|
|
|
"TODO"
|
2019-07-21 15:39:45 +02:00
|
|
|
(car (gethash (symbol-name package) straight--build-cache)))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
2019-07-21 15:39:45 +02:00
|
|
|
(defun doom-package-dependencies (package &optional recursive noerror)
|
|
|
|
"Return a list of dependencies for a package."
|
|
|
|
(let ((deps (nth 1 (gethash (symbol-name package) straight--build-cache))))
|
|
|
|
(if recursive
|
|
|
|
(nconc deps (mapcan (lambda (dep) (doom-package-dependencies dep t t))
|
|
|
|
deps))
|
|
|
|
deps)))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
2020-01-26 21:21:06 -05:00
|
|
|
;;;###autoload
|
2019-07-21 15:39:45 +02:00
|
|
|
(defun doom-package-depending-on (package &optional noerror)
|
|
|
|
"Return a list of packages that depend on the package named NAME."
|
|
|
|
(cl-check-type name symbol)
|
|
|
|
;; can't get dependencies for built-in packages
|
|
|
|
(unless (or (doom-package-build-recipe name)
|
|
|
|
noerror)
|
|
|
|
(error "Couldn't find %s, is it installed?" name))
|
|
|
|
(cl-loop for pkg in (hash-table-keys straight--build-cache)
|
|
|
|
for deps = (doom-package-dependencies pkg)
|
|
|
|
if (memq package deps)
|
|
|
|
collect pkg
|
|
|
|
and append (doom-package-depending-on pkg t)))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
;;; Predicate functions
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-built-in-p (package)
|
|
|
|
"Return non-nil if PACKAGE (a symbol) is built-in."
|
2019-07-21 15:39:45 +02:00
|
|
|
(eq (doom-package-build-recipe package :type)
|
|
|
|
'built-in))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-installed-p (package)
|
|
|
|
"Return non-nil if PACKAGE (a symbol) is installed."
|
2019-07-21 15:39:45 +02:00
|
|
|
(file-directory-p (straight--build-dir (symbol-name package))))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-registered-p (package)
|
|
|
|
"Return non-nil if PACKAGE (a symbol) has been registered with `package!'.
|
|
|
|
|
|
|
|
Excludes packages that have a non-nil :built-in property."
|
2019-07-21 15:39:45 +02:00
|
|
|
(when-let (plist (doom-package-get package))
|
2019-11-17 16:43:23 -05:00
|
|
|
(not (plist-get plist :ignore))))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-private-p (package)
|
|
|
|
"Return non-nil if PACKAGE was installed by the user's private config."
|
2019-07-26 15:25:30 +02:00
|
|
|
(assq :private (doom-package-get package :modules)))
|
2017-02-03 07:58:16 -05:00
|
|
|
|
2019-06-11 08:01:42 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-protected-p (package)
|
|
|
|
"Return non-nil if PACKAGE is protected.
|
|
|
|
|
|
|
|
A protected package cannot be deleted and will be auto-installed if missing."
|
2019-07-21 15:39:45 +02:00
|
|
|
(memq package doom-core-packages))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-core-p (package)
|
|
|
|
"Return non-nil if PACKAGE is a core Doom package."
|
|
|
|
(or (doom-package-protected-p package)
|
2019-07-21 15:39:45 +02:00
|
|
|
(assq :core (doom-package-get package :modules))))
|
2019-06-11 08:01:42 +02:00
|
|
|
|
2019-07-28 23:27:17 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-backend (package)
|
|
|
|
"Return 'straight, 'builtin, 'elpa or 'other, depending on how PACKAGE is
|
|
|
|
installed."
|
|
|
|
(cond ((gethash (symbol-name package) straight--build-cache)
|
|
|
|
'straight)
|
|
|
|
((or (doom-package-built-in-p package)
|
|
|
|
(assq package package--builtins))
|
|
|
|
'builtin)
|
|
|
|
((assq package package-alist)
|
|
|
|
'elpa)
|
|
|
|
('other)))
|
|
|
|
|
2019-06-11 08:01:42 +02:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-different-recipe-p (name)
|
|
|
|
"Return t if a package named NAME (a symbol) has a different recipe than it
|
|
|
|
was installed with."
|
|
|
|
(cl-check-type name symbol)
|
2019-07-21 15:39:45 +02:00
|
|
|
;; TODO
|
|
|
|
;; (when (doom-package-installed-p name)
|
|
|
|
;; (when-let* ((doom-recipe (assq name doom-packages))
|
|
|
|
;; (install-recipe (doom-package-recipe)))
|
|
|
|
;; (not (equal (cdr quelpa-recipe)
|
|
|
|
;; (cdr (plist-get (cdr doom-recipe) :recipe))))))
|
|
|
|
)
|
2017-02-03 07:58:16 -05:00
|
|
|
|
2018-09-07 21:52:11 -04:00
|
|
|
|
2019-06-11 08:01:42 +02:00
|
|
|
;;
|
|
|
|
;;; Package list getters
|
2018-02-20 17:55:53 -05:00
|
|
|
|
2019-09-14 18:27:02 -04:00
|
|
|
(defun doom--read-module-packages-file (file &optional noeval noerror)
|
2019-03-10 08:10:59 -04:00
|
|
|
(with-temp-buffer ; prevent buffer-local settings from propagating
|
|
|
|
(condition-case e
|
2019-09-14 18:27:02 -04:00
|
|
|
(if (not noeval)
|
2019-03-10 08:10:59 -04:00
|
|
|
(load file noerror t t)
|
|
|
|
(when (file-readable-p file)
|
|
|
|
(insert-file-contents file)
|
2019-07-21 15:39:45 +02:00
|
|
|
(delay-mode-hooks (emacs-lisp-mode))
|
2019-10-13 12:25:41 +09:00
|
|
|
(while (search-forward "(package! " nil t)
|
2019-03-10 08:10:59 -04:00
|
|
|
(save-excursion
|
|
|
|
(goto-char (match-beginning 0))
|
2019-07-26 20:17:09 +02:00
|
|
|
(unless (let ((ppss (syntax-ppss)))
|
|
|
|
(or (nth 3 ppss)
|
|
|
|
(nth 4 ppss)))
|
|
|
|
(cl-destructuring-bind (name . plist)
|
|
|
|
(cdr (sexp-at-point))
|
|
|
|
(push (cons
|
|
|
|
name (plist-put
|
|
|
|
plist :modules
|
|
|
|
(list (doom-module-from-path file))))
|
2019-07-21 15:39:45 +02:00
|
|
|
doom-packages)))))))
|
2019-03-10 08:10:59 -04:00
|
|
|
((debug error)
|
|
|
|
(signal 'doom-package-error
|
2019-07-26 20:17:09 +02:00
|
|
|
(list (doom-module-from-path file)
|
2020-01-11 17:27:04 -05:00
|
|
|
file
|
2019-03-10 08:10:59 -04:00
|
|
|
e))))))
|
|
|
|
|
2019-03-06 00:26:33 -05:00
|
|
|
;;;###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'.
|
|
|
|
|
2019-03-10 08:10:59 -04:00
|
|
|
If ALL-P, gather packages unconditionally across all modules, including disabled
|
|
|
|
ones."
|
2019-09-03 00:36:42 -04:00
|
|
|
(let ((doom-interactive-mode t)
|
2019-03-10 08:10:59 -04:00
|
|
|
(doom-modules (doom-modules))
|
2019-12-24 00:01:17 -05:00
|
|
|
doom-packages)
|
2019-07-21 15:39:45 +02:00
|
|
|
(doom--read-module-packages-file
|
2019-07-26 20:17:09 +02:00
|
|
|
(doom-path doom-core-dir "packages.el") all-p t)
|
|
|
|
(let ((private-packages (doom-path doom-private-dir "packages.el")))
|
2019-03-10 08:10:59 -04:00
|
|
|
(unless all-p
|
|
|
|
;; 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.
|
2019-10-25 02:36:02 -04:00
|
|
|
(doom--read-module-packages-file private-packages nil t))
|
2019-03-10 08:10:59 -04:00
|
|
|
(if all-p
|
|
|
|
(mapc #'doom--read-module-packages-file
|
|
|
|
(doom-files-in doom-modules-dir
|
|
|
|
:depth 2
|
2019-07-21 23:31:42 +02:00
|
|
|
:match "/packages\\.el$"))
|
2019-03-10 08:10:59 -04:00
|
|
|
(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 (doom--read-module-packages-file path nil t)))
|
|
|
|
(doom--read-module-packages-file private-packages all-p t))
|
2019-07-21 15:39:45 +02:00
|
|
|
(nreverse doom-packages)))
|
2020-01-26 21:21:06 -05:00
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defun doom-package-recipe-list ()
|
|
|
|
"Return straight recipes for non-builtin packages with a local-repo."
|
|
|
|
(let (recipes)
|
|
|
|
(dolist (recipe (hash-table-values straight--recipe-cache))
|
|
|
|
(with-plist! recipe (local-repo type)
|
|
|
|
(when (and local-repo (not (eq type 'built-in)))
|
|
|
|
(push recipe recipes))))
|
|
|
|
(nreverse recipes)))
|
|
|
|
|
|
|
|
;;;###autoload
|
|
|
|
(defmacro doom-with-package-recipes (recipes binds &rest body)
|
|
|
|
"TODO"
|
|
|
|
(declare (indent 2))
|
|
|
|
(let ((recipe-var (make-symbol "recipe"))
|
|
|
|
(recipes-var (make-symbol "recipes")))
|
|
|
|
`(let* ((,recipes-var ,recipes)
|
|
|
|
(built ())
|
|
|
|
(straight-use-package-pre-build-functions
|
|
|
|
(cons (lambda (pkg) (cl-pushnew pkg built :test #'equal))
|
|
|
|
straight-use-package-pre-build-functions)))
|
|
|
|
(dolist (,recipe-var ,recipes-var)
|
|
|
|
(cl-block nil
|
|
|
|
(straight--with-plist (append (list :recipe ,recipe-var) ,recipe-var)
|
|
|
|
,(doom-enlist binds)
|
|
|
|
,@body)))
|
|
|
|
(nreverse built))))
|
2017-02-03 07:58:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
;;
|
2019-07-21 15:39:45 +02:00
|
|
|
;;; Main functions
|
2017-02-02 19:15:58 -05:00
|
|
|
|
2019-03-06 00:26:33 -05:00
|
|
|
;;;###autoload
|
|
|
|
(defun doom/reload-packages ()
|
|
|
|
"Reload `doom-packages', `package' and `quelpa'."
|
|
|
|
(interactive)
|
2019-07-30 14:44:10 +03:00
|
|
|
;; HACK straight.el must be loaded for this to work
|
2019-03-06 00:26:33 -05:00
|
|
|
(message "Reloading packages")
|
|
|
|
(doom-initialize-packages t)
|
|
|
|
(message "Reloading packages...DONE"))
|
2020-01-14 21:46:09 -05:00
|
|
|
|
|
|
|
;;;###autoload
|
2020-01-25 04:14:40 -05:00
|
|
|
(defun doom/update-pinned-package-form (&optional select)
|
2020-01-14 21:46:09 -05:00
|
|
|
"Inserts or updates a `:pin' for the `package!' statement at point.
|
|
|
|
|
|
|
|
Grabs the latest commit id of the package using 'git'."
|
2020-01-25 04:14:40 -05:00
|
|
|
(interactive "P")
|
2020-01-14 21:46:09 -05:00
|
|
|
;; REVIEW Better error handling
|
|
|
|
;; TODO Insert a new `package!' if no `package!' at poin
|
2020-01-15 00:50:27 -05:00
|
|
|
(require 'straight)
|
2020-01-14 21:46:09 -05:00
|
|
|
(ignore-errors
|
2020-01-15 00:48:57 -05:00
|
|
|
(while (and (atom (sexp-at-point))
|
|
|
|
(not (bolp)))
|
2020-01-14 21:46:09 -05:00
|
|
|
(forward-sexp -1)))
|
2020-01-25 04:14:40 -05:00
|
|
|
(save-excursion
|
|
|
|
(if (not (eq (sexp-at-point) 'package!))
|
|
|
|
(user-error "Not on a `package!' call")
|
|
|
|
(backward-char)
|
|
|
|
(let* ((recipe (cdr (sexp-at-point)))
|
|
|
|
(name (car recipe))
|
|
|
|
(id
|
|
|
|
(cdr (doom-call-process
|
|
|
|
"git" "ls-remote"
|
|
|
|
(straight-vc-git--destructure
|
|
|
|
(doom-plist-merge
|
|
|
|
(plist-get (cdr recipe) :recipe)
|
|
|
|
(or (cdr (straight-recipes-retrieve name))
|
|
|
|
(plist-get (cdr (assq name doom-packages)) :recipe)))
|
|
|
|
(upstream-repo upstream-host)
|
|
|
|
(straight-vc-git--encode-url upstream-repo upstream-host))))))
|
|
|
|
(unless id
|
|
|
|
(user-error "No id for %S package" name))
|
|
|
|
(let* ((id (if select
|
|
|
|
(car (split-string (completing-read "Commit: " (split-string id "\n" t))))
|
|
|
|
(car (split-string id))))
|
|
|
|
(id (substring id 0 10)))
|
|
|
|
(if (re-search-forward ":pin +\"\\([^\"]+\\)\"" (cdr (bounds-of-thing-at-point 'sexp)) t)
|
|
|
|
(replace-match id t t nil 1)
|
|
|
|
(thing-at-point--end-of-sexp)
|
|
|
|
(backward-char)
|
|
|
|
(insert " :pin " (prin1-to-string id))))))))
|