Subject: [PATCH] Add package-delete-regexp

From: "Marwan L." <[email-masked]>
Date: Tue, 17 May 2022 00:25:30 +0100

This function allows you to delete packages, with names that match the
regexp. This is makes operations like deleting multiple packages that
begin with the same namespace (^company.*, ^treemacs.*, etc.) much
easier to do

The function will also tell you how much packages it will delete (in a
temporary buffer) and prompt for a Yes or No answer

diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index f356a2bf60..a166b0ef47 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -2400,6 +2400,33 @@ If NOSAVE is non-nil, the package is not removed from
            (message "Package `%s' deleted."
                     (package-desc-full-name pkg-desc))))))
 
+(defun package-delete-regexp (pkg-regexp &optional force nosave)
+  "Delete packages matching the regexp PKG-REGEXP
+This will use `package-delete' to delete packages"
+  (interactive
+   (let ((pkg-regexp (read-string "Delete packages (regexp): ")))
+     (list pkg-regexp)))
+
+  ;;; Search through every package name and match it with the user's regexp
+  ;;; and filter out the nil's
+  (let ((pkg-list (remq nil
+                        (mapcar
+			 (lambda (elem)
+                           (if (string-match pkg-regexp (package-desc-full-name (nth 1 elem)))
+			       (nth 1 elem)))
+			 (package--alist)))))
+    (if (length> pkg-list 0) 
+	(with-output-to-temp-buffer "Package Deletion"
+	  (pop-to-buffer "Package Deletion")
+	  (princ "This operation will delete these following packages: \n")
+	  (dolist (elem pkg-list)
+	    (princ (format "%s\n" (package-desc-full-name elem))))
+	  (if (y-or-n-p "Delete? ")
+	      (dolist (elem pkg-list)
+		(package-delete elem force nosave)))
+	  (kill-current-buffer))
+      (message "No packages found"))))
+
 ;;;###autoload
 (defun package-reinstall (pkg)
   "Reinstall package PKG.