;;; core/autoload/packages.el -*- lexical-binding: t; -*- ;;;###autoload (defun doom/reload-packages () "Reload `doom-packages', `package' and `quelpa'." (interactive) ;; HACK straight.el must be loaded for this to work (message "Reloading packages") (doom-initialize-packages t) (message "Reloading packages...DONE")) ;; ;;; Bump commands (defun doom--package-full-recipe (package plist) (doom-plist-merge (plist-get plist :recipe) (or (cdr (straight-recipes-retrieve package)) (plist-get (cdr (assq package doom-packages)) :recipe)))) (defun doom--package-to-bump-string (package plist) "Return a PACKAGE and its PLIST in 'username/repo@commit' format." (format "%s@%s" (plist-get (doom--package-full-recipe package plist) :repo) (substring-no-properties (plist-get plist :pin) 0 7))) (defun doom--package-at-point (&optional point) "Return the package and plist from the (package! PACKAGE PLIST...) at point." (save-match-data (save-excursion (and point (goto-char point)) (if (eq (sexp-at-point) 'package!) (progn (backward-sexp) (backward-char) t) (while (and (search-backward "(package!" nil t) (doom-point-in-string-or-comment-p)))) (unless (or (doom-point-in-string-or-comment-p) (not (eq (car-safe (sexp-at-point)) 'package!))) (cl-destructuring-bind (beg . end) (bounds-of-thing-at-point 'sexp) (let ((package (let (doom-packages) (eval (sexp-at-point) t)))) (list :beg beg :end end :package (car package) :plist (cdr package)))))))) ;;;###autoload (defun doom/bumpify-package-at-point () "Convert `package!' call at point to a bump string." (interactive) (cl-destructuring-bind (&key package plist beg end) (doom--package-at-point) (when-let (str (doom--package-to-bump-string package plist)) (goto-char beg) (delete-region beg end) (insert str)))) ;;;###autoload (defun doom/bumpify-packages-in-buffer () "Convert all `package!' calls in buffer into bump strings." (interactive) (save-excursion (goto-char (point-min)) (while (search-forward "(package!" nil t) (unless (doom-point-in-string-or-comment-p) (doom/bumpify-package-at-point))))) ;;;###autoload (defun doom/bump-package-at-point (&optional select) "Inserts or updates a `:pin' for the `package!' statement at point. Grabs the latest commit id of the package using 'git'." (interactive "P") (doom-initialize-packages) (cl-destructuring-bind (&key package plist beg end) (or (doom--package-at-point) (user-error "Not on a `package!' call")) (let* ((recipe (doom--package-full-recipe package plist)) (branch (or (plist-get recipe :branch) straight-vc-git-default-branch)) (oldid (or (plist-get plist :pin) (doom-package-get package :pin))) id url) (when (or (eq (plist-get plist :built-in) t) (and (eq (plist-get plist :built-in) 'prefer) (locate-library (symbol-name package)))) (user-error "%s: skipping built-in package" package)) (setq url (straight-vc-git--destructure recipe (upstream-repo upstream-host) (straight-vc-git--encode-url upstream-repo upstream-host)) id (when url (cdr (doom-call-process "git" "ls-remote" url (unless select (or branch straight-vc-git-default-branch)))))) (unless id (user-error "%s: no id from %s" package url)) (let* ((id (car (split-string (if select (completing-read "Commit: " (split-string id "\n" t)) id))))) (when (and oldid (equal oldid id)) (user-error "%s: no update necessary" package)) (save-excursion (if (re-search-forward ":pin +\"\\([^\"]+\\)\"" end t) (replace-match id t t nil 1) (thing-at-point--end-of-sexp) (backward-char) (insert " :pin " (prin1-to-string id)))) (message "Updated %S: %s -> %s" package (substring oldid 0 10) (substring id 0 10)))))) ;;;###autoload (defun doom/bump-packages-in-buffer (&optional select) "Inserts or updates a `:pin' for the `package!' statement at point. Grabs the latest commit id of the package using 'git'." (interactive "P") (save-excursion (goto-char (point-min)) (doom-initialize-packages) (let (packages) (while (search-forward "(package! " nil t) (unless (let ((ppss (syntax-ppss))) (or (nth 4 ppss) (nth 3 ppss) (save-excursion (and (goto-char (match-beginning 0)) (not (plist-member (sexp-at-point) :pin)))))) (condition-case e (push (doom/bump-package-at-point) packages) (user-error (message "%s" (error-message-string e)))))) (if packages (message "Updated %d packages\n- %s" (length packages) (string-join packages "\n- ")) (message "No packages to update"))))) ;;;###autoload (defun doom/bump-module (category &optional module select) "Bump packages in CATEGORY MODULE. If SELECT (prefix arg) is non-nil, prompt you to choose a specific commit for each package." (interactive (append (mapcar #'intern (split-string (completing-read "Bump module: " (let ((modules (doom-module-list 'all))) (mapcar (lambda (m) (if (listp m) (format "%s %s" (car m) (cdr m)) (format "%s" m))) (append (list ":private") (delete-dups (mapcar #'car modules)) modules))) nil t nil nil) " " t)) (list current-prefix-arg))) (if-let (packages-file (if (eq category :private) (doom-glob doom-private-dir "packages.el") (doom-module-locate-path category module "packages.el"))) (with-current-buffer (or (get-file-buffer packages-file) (find-file-noselect packages-file)) (doom/bump-packages-in-buffer select)) (user-error "Module %s %s has no packages.el file"))) ;;;###autoload (defun doom/bump-package (package) "Bump PACKAGE in all modules that install it." (interactive (list (completing-read "Bump package: " (mapcar #'car (doom-package-list 'all))))) (let* ((packages (doom-package-list 'all)) (modules (plist-get (alist-get package packages) :modules))) (unless modules (user-error "This package isn't installed by any Doom module")) (dolist (module modules) (when-let (packages-file (doom-module-locate-path (car module) (cdr module))) (doom/bump-module (car module) (cdr module)))))) ;; ;;; Bump commits ;;;###autoload (defun doom/commit-bumps () (interactive))