summary refs log tree commit diff
path: root/emacs/elisp/my-packages-extra.el
blob: de3775214818a24b079ec965d6c916fe9cb5ab7c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
;;; my-packages-extra.el --- Provides additional functions related to
;;; packages

;;; Commentary:

;;; Code:

(require 'package)

;; Original idea: https://www.manueluberti.eu/emacs/2021/09/01/package-report/
(defun my/package-report ()
  "Report total package counts grouped by archive."
  (interactive)
  (package-refresh-contents)
  (my/display-package-report
   (let* ((arch-pkgs (my/archive-packages))
          (counts (seq-sort-by #'cdr #'> (my/archive-counts arch-pkgs)))
          (by-arch (seq-group-by #'car arch-pkgs)))
     (concat
      (format "Total packages: %s\n\n" (apply #'+ (mapcar #'cdr counts)))
      (mapconcat
       (lambda (archive)
         (concat "• "
                 (format "%s (%s)" (car archive) (cdr archive))
                 ": "
                 (mapconcat (lambda (ap-pair) (cdr ap-pair))
                            (alist-get (car archive) by-arch)
                            ", ")))
       counts
       "\n\n")))))

(defun my/display-package-report (output)
  "Display OUTPUT in a popup buffer."
  (let ((buffer-name "*package-report*"))
    (with-help-window buffer-name
      (with-current-buffer buffer-name
        (visual-line-mode 1)
        (erase-buffer)
        (insert output)
        (goto-char (point-min))))))

(defun my/archive-packages ()
  "Return a list of (archive . package) cons cells."
  (seq-reduce
   (lambda (res package)
     (let ((archive (package-desc-archive
                     (cadr (assq package package-archive-contents))))
           (pkg (symbol-name package)))
       (push (cons archive pkg) res)))
   (mapcar #'car package-alist)
   nil))

(defun my/archive-counts (arch-pkgs)
  "Return a list of cons cells from alist ARCH-PKGS.
The cars are package archives, the cdrs are the number of
packages installed from each archive."
  (seq-reduce
   (lambda (counts key)
     (cons (cons key (+ 1 (or (cdr (assoc key counts)) 0)))
           (assoc-delete-all key counts)))
   (mapcar #'car arch-pkgs)
   nil))

(provide 'my-packages-extra)
;;; my-packages-extra.el ends here