aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/emacs-lisp/package.el4656
1 files changed, 4656 insertions, 0 deletions
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
new file mode 100644
index 00000000000..f37c17f201f
--- /dev/null
+++ b/lisp/emacs-lisp/package.el
@@ -0,0 +1,4656 @@
1;;; package.el --- Simple package system for Emacs -*- lexical-binding:t -*-
2
3;; Copyright (C) 2007-2026 Free Software Foundation, Inc.
4
5;; Author: Tom Tromey <tromey@redhat.com>
6;; Daniel Hackney <dan@haxney.org>
7;; Created: 10 Mar 2007
8;; Version: 1.1.0
9;; Keywords: tools
10;; Package-Requires: ((tabulated-list "1.0"))
11
12;; This file is part of GNU Emacs.
13
14;; GNU Emacs is free software: you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
16;; the Free Software Foundation, either version 3 of the License, or
17;; (at your option) any later version.
18
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
23
24;; You should have received a copy of the GNU General Public License
25;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
26
27;;; Commentary:
28
29;; The idea behind package.el is to be able to download packages and
30;; install them. Packages are versioned and have versioned
31;; dependencies. Furthermore, this supports built-in packages which
32;; may or may not be newer than user-specified packages. This makes
33;; it possible to upgrade Emacs and automatically disable packages
34;; which have moved from external to core. (Note though that we don't
35;; currently register any of these, so this feature does not actually
36;; work.)
37
38;; A package is described by its name and version. The distribution
39;; format is either a tar file or a single .el file.
40
41;; A tar file should be named "NAME-VERSION.tar". The tar file must
42;; unpack into a directory named after the package and version:
43;; "NAME-VERSION". It must contain a file named "PACKAGE-pkg.el"
44;; which consists of a call to define-package. It may also contain a
45;; "dir" file and the info files it references.
46
47;; A .el file is named "NAME-VERSION.el" in the remote archive, but is
48;; installed as simply "NAME.el" in a directory named "NAME-VERSION".
49
50;; The downloader downloads all dependent packages. By default,
51;; packages come from the official GNU sources, but others may be
52;; added by customizing the `package-archives' alist. Packages get
53;; byte-compiled at install time.
54
55;; At activation time we will set up the load-path and the info path,
56;; and we will load the package's autoloads. If a package's
57;; dependencies are not available, we will not activate that package.
58
59;; Conceptually a package has multiple state transitions:
60;;
61;; * Download. Fetching the package from ELPA.
62;; * Install. Untar the package, or write the .el file, into
63;; ~/.emacs.d/elpa/ directory.
64;; * Autoload generation.
65;; * Byte compile. Currently this phase is done during install,
66;; but we may change this.
67;; * Activate. Evaluate the autoloads for the package to make it
68;; available to the user.
69;; * Load. Actually load the package and run some code from it.
70
71;; Other external functions you may want to use:
72;;
73;; M-x list-packages
74;; Enters a mode similar to buffer-menu which lets you manage
75;; packages. You can choose packages for install (mark with "i",
76;; then "x" to execute) or deletion, and you can see what packages
77;; are available. This will automatically fetch the latest list of
78;; packages from ELPA.
79;;
80;; M-x package-install-from-buffer
81;; Install a package consisting of a single .el file that appears
82;; in the current buffer. This only works for packages which
83;; define a Version header properly; package.el also supports the
84;; extension headers Package-Version (in case Version is an RCS id
85;; or similar), and Package-Requires (if the package requires other
86;; packages).
87;;
88;; M-x package-install-file
89;; Install a package from the indicated file. The package can be
90;; either a tar file or a .el file. A tar file must contain an
91;; appropriately-named "-pkg.el" file; a .el file must be properly
92;; formatted as with `package-install-from-buffer'.
93
94;;; Thanks:
95;;; (sorted by sort-lines):
96
97;; Jim Blandy <jimb@red-bean.com>
98;; Karl Fogel <kfogel@red-bean.com>
99;; Kevin Ryde <user42@zip.com.au>
100;; Lawrence Mitchell
101;; Michael Olson <mwolson@member.fsf.org>
102;; Sebastian Tennant <sebyte@smolny.plus.com>
103;; Stefan Monnier <monnier@iro.umontreal.ca>
104;; Vinicius Jose Latorre <viniciusjl.gnu@gmail.com>
105;; Phil Hagelberg <phil@hagelb.org>
106
107;;; ToDo:
108
109;; - putting info dirs at the start of the info path means
110;; users see a weird ordering of categories. OTOH we want to
111;; override later entries. maybe emacs needs to enforce
112;; the standard layout?
113;; - put bytecode in a separate directory tree
114;; - perhaps give users a way to recompile their bytecode
115;; or do it automatically when emacs changes
116;; - give users a way to know whether a package is installed ok
117;; - give users a way to view a package's documentation when it
118;; only appears in the .el
119;; - use/extend checkdoc so people can tell if their package will work
120;; - "installed" instead of a blank in the status column
121;; - tramp needs its files to be compiled in a certain order.
122;; how to handle this? fix tramp?
123;; - maybe we need separate .elc directories for various emacs
124;; versions. That way conditional compilation can work. But would
125;; this break anything?
126;; - William Xu suggests being able to open a package file without
127;; installing it
128;; - Interface with desktop.el so that restarting after an install
129;; works properly
130;; - Use hierarchical layout. PKG/etc PKG/lisp PKG/info
131;; ... except maybe lisp?
132;; - It may be nice to have a macro that expands to the package's
133;; private data dir, aka ".../etc". Or, maybe data-directory
134;; needs to be a list (though this would be less nice)
135;; a few packages want this, eg sokoban
136;; - Allow multiple versions on the server, so that if a user doesn't
137;; meet the requirements for the most recent version they can still
138;; install an older one.
139;; - Allow optional package dependencies
140;; then if we require 'bbdb', bbdb-specific lisp in lisp/bbdb
141;; and just don't compile to add to load path ...?
142;; - Our treatment of the info path is somewhat bogus
143
144;;; Code:
145
146(require 'package-core)
147
148(require 'cl-lib)
149(eval-when-compile (require 'subr-x))
150(eval-when-compile (require 'epg)) ;For setf accessors.
151(eval-when-compile (require 'inline)) ;For `define-inline'
152(require 'seq)
153
154(require 'tabulated-list)
155(require 'macroexp)
156(require 'url-handlers)
157(require 'browse-url)
158
159(defgroup package nil
160 "Manager for Emacs Lisp packages."
161 :group 'applications
162 :version "24.1")
163
164
165;;; Customization options
166
167;;;###autoload
168(defcustom package-enable-at-startup t
169 "Whether to make installed packages available when Emacs starts.
170If non-nil, packages are made available before reading the init
171file (but after reading the early init file). This means that if
172you wish to set this variable, you must do so in the early init
173file. Regardless of the value of this variable, packages are not
174made available if `user-init-file' is nil (e.g. Emacs was started
175with \"-q\").
176
177Even if the value is nil, you can type \\[package-initialize] to
178make installed packages available at any time, or you can
179call (package-activate-all) in your init-file.
180
181Note that this variable must be set to a non-default value in
182your early-init file, as the variable's value is used before
183loading the regular init file. Therefore, if you customize it
184via Customize, you should save your customized setting into
185your `early-init-file'."
186 :type 'boolean
187 :version "24.1")
188
189;;;###autoload
190(defcustom package-load-list '(all)
191 "List of packages for `package-activate-all' to make available.
192Each element in this list should be a list (NAME VERSION), or the
193symbol `all'. The symbol `all' says to make available the latest
194installed versions of all packages not specified by other
195elements.
196
197For an element (NAME VERSION), NAME is a package name (a symbol).
198VERSION should be t, a string, or nil.
199If VERSION is t, the most recent version is made available.
200If VERSION is a string, only that version is ever made available.
201 Any other version, even if newer, is silently ignored.
202 Hence, the package is \"held\" at that version.
203If VERSION is nil, the package is not made available (it is \"disabled\")."
204 :type '(repeat (choice (const all)
205 (list :tag "Specific package"
206 (symbol :tag "Package name")
207 (choice :tag "Version"
208 (const :tag "disable" nil)
209 (const :tag "most recent" t)
210 (string :tag "specific version")))))
211 :risky t
212 :version "24.1")
213
214(defcustom package-archives `(("gnu" .
215 ,(format "http%s://elpa.gnu.org/packages/"
216 (if (gnutls-available-p) "s" "")))
217 ("nongnu" .
218 ,(format "http%s://elpa.nongnu.org/nongnu/"
219 (if (gnutls-available-p) "s" ""))))
220 "An alist of archives from which to fetch.
221The default value points to the GNU Emacs package repository.
222
223Each element has the form (ID . LOCATION).
224 ID is an archive name, as a string.
225 LOCATION specifies the base location for the archive.
226 If it starts with \"http(s):\", it is treated as an HTTP(S) URL;
227 otherwise it should be an absolute directory name.
228 (Other types of URL are currently not supported.)
229
230Only add locations that you trust, since fetching and installing
231a package can run arbitrary code.
232
233HTTPS URLs should be used where possible, as they offer superior
234security."
235 :type '(alist :key-type (string :tag "Archive name")
236 :value-type (string :tag "URL or directory name"))
237 :risky t
238 :version "28.1")
239
240(defcustom package-menu-hide-low-priority 'archive
241 "If non-nil, hide low priority packages from the packages menu.
242A package is considered low priority if there's another version
243of it available such that:
244 (a) the archive of the other package is higher priority than
245 this one, as per `package-archive-priorities';
246 or
247 (b) they both have the same archive priority but the other
248 package has a higher version number.
249
250This variable has three possible values:
251 nil: no packages are hidden;
252 `archive': only criterion (a) is used;
253 t: both criteria are used.
254
255This variable has no effect if `package-menu--hide-packages' is
256nil, so it can be toggled with \\<package-menu-mode-map>\\[package-menu-toggle-hiding]."
257 :type '(choice (const :tag "Don't hide anything" nil)
258 (const :tag "Hide per package-archive-priorities"
259 archive)
260 (const :tag "Hide per archive and version number" t))
261 :version "25.1")
262
263(defcustom package-archive-priorities nil
264 "An alist of priorities for packages.
265
266Each element has the form (ARCHIVE-ID . PRIORITY).
267
268When installing packages, the package with the highest version
269number from the archive with the highest priority is
270selected. When higher versions are available from archives with
271lower priorities, the user has to select those manually.
272
273Archives not in this list have the priority 0, as have packages
274that are already installed. If you use negative priorities for
275the archives, they will not be upgraded automatically.
276
277See also `package-menu-hide-low-priority'."
278 :type '(alist :key-type (string :tag "Archive name")
279 :value-type (integer :tag "Priority (default is 0)"))
280 :risky t
281 :version "25.1")
282
283(defcustom package-pinned-packages nil
284 "An alist of packages that are pinned to specific archives.
285This can be useful if you have multiple package archives enabled,
286and want to control which archive a given package gets installed from.
287
288Each element of the alist has the form (PACKAGE . ARCHIVE), where:
289 PACKAGE is a symbol representing a package
290 ARCHIVE is a string representing an archive (it should be the car of
291an element in `package-archives', e.g. \"gnu\").
292
293Adding an entry to this variable means that only ARCHIVE will be
294considered as a source for PACKAGE. If other archives provide PACKAGE,
295they are ignored (for this package). If ARCHIVE does not contain PACKAGE,
296the package will be unavailable."
297 :type '(alist :key-type (symbol :tag "Package")
298 :value-type (string :tag "Archive name"))
299 ;; This could prevent you from receiving updates for a package,
300 ;; via an entry (PACKAGE . NON-EXISTING). Which could be an issue
301 ;; if PACKAGE has a known vulnerability that is fixed in newer versions.
302 :risky t
303 :version "24.4")
304
305;;;###autoload
306(defcustom package-user-dir (locate-user-emacs-file "elpa")
307 "Directory containing the user's Emacs Lisp packages.
308The directory name should be absolute.
309Apart from this directory, Emacs also looks for system-wide
310packages in `package-directory-list'."
311 :type 'directory
312 :initialize #'custom-initialize-delay
313 :risky t
314 :group 'applications
315 :version "24.1")
316
317;;;###autoload
318(defcustom package-directory-list
319 ;; Defaults are subdirs named "elpa" in the site-lisp dirs.
320 (let (result)
321 (dolist (f load-path)
322 (and (stringp f)
323 (equal (file-name-nondirectory f) "site-lisp")
324 (push (expand-file-name "elpa" f) result)))
325 (nreverse result))
326 "List of additional directories containing Emacs Lisp packages.
327Each directory name should be absolute.
328
329These directories contain packages intended for system-wide; in
330contrast, `package-user-dir' contains packages for personal use."
331 :type '(repeat directory)
332 :initialize #'custom-initialize-delay
333 :group 'applications
334 :risky t
335 :version "24.1")
336
337(declare-function epg-find-configuration "epg-config"
338 (protocol &optional no-cache program-alist))
339
340(defcustom package-gnupghome-dir (expand-file-name "gnupg" package-user-dir)
341 "Directory containing GnuPG keyring or nil.
342This variable specifies the GnuPG home directory used by package.
343That directory is passed via the option \"--homedir\" to GnuPG.
344If nil, do not use the option \"--homedir\", but stick with GnuPG's
345default directory."
346 :type `(choice
347 (const
348 :tag "Default Emacs package management GnuPG home directory"
349 ,(expand-file-name "gnupg" package-user-dir))
350 (const
351 :tag "Default GnuPG directory (GnuPG option --homedir not used)"
352 nil)
353 (directory :tag "A specific GnuPG --homedir"))
354 :risky t
355 :version "26.1")
356
357(defcustom package-check-signature 'allow-unsigned
358 "Non-nil means to check package signatures when installing.
359
360This also applies to the \"archive-contents\" file that lists the
361contents of the archive.
362
363The value can be one of:
364
365 t Accept a package only if it comes with at least
366 one verified signature.
367
368 `all' Same as t, but verify all signatures if there
369 are more than one.
370
371 `allow-unsigned' Install a package even if it is unsigned,
372 but verify the signature if possible (that
373 is, if it is signed, we have the key for it,
374 and GnuPG is installed).
375
376 nil Package signatures are ignored."
377 :type '(choice (const :value nil :tag "Never")
378 (const :value allow-unsigned :tag "Allow unsigned")
379 (const :value t :tag "Check always")
380 (const :value all :tag "Check always (all signatures)"))
381 :risky t
382 :version "27.1")
383
384(defun package-check-signature ()
385 "Check whether we have a usable OpenPGP configuration.
386If so, and variable `package-check-signature' is
387`allow-unsigned', return `allow-unsigned', otherwise return the
388value of variable `package-check-signature'."
389 (if (eq package-check-signature 'allow-unsigned)
390 (and (epg-find-configuration 'OpenPGP)
391 'allow-unsigned)
392 package-check-signature))
393
394(defcustom package-unsigned-archives nil
395 "List of archives where we do not check for package signatures.
396This should be a list of strings matching the names of package
397archives in the variable `package-archives'."
398 :type '(repeat (string :tag "Archive name"))
399 :risky t
400 :version "24.4")
401
402(defcustom package-selected-packages nil
403 "Store here packages installed explicitly by user.
404This variable is fed automatically by Emacs when installing a new package.
405This variable is used by `package-autoremove' to decide
406which packages are no longer needed.
407You can use it to (re)install packages on other machines
408by running `package-install-selected-packages'.
409
410To check if a package is contained in this list here, use
411`package--user-selected-p', as it may populate the variable with
412a sane initial value."
413 :version "25.1"
414 :type '(repeat symbol))
415
416(defcustom package-native-compile nil
417 "Non-nil means to natively compile packages as part of their installation.
418This controls ahead-of-time compilation of packages when they are
419installed. If this option is nil, packages will be natively
420compiled when they are loaded for the first time.
421
422This option does not have any effect if Emacs was not built with
423native compilation support."
424 :type '(boolean)
425 :risky t
426 :version "28.1")
427
428(defcustom package-menu-async t
429 "If non-nil, package-menu will use async operations when possible.
430Currently, only the refreshing of archive contents supports
431asynchronous operations. Package transactions are still done
432synchronously."
433 :type 'boolean
434 :version "25.1")
435
436(defcustom package-name-column-width 30
437 "Column width for the Package name in the package menu."
438 :type 'natnum
439 :version "28.1")
440
441(defcustom package-version-column-width 14
442 "Column width for the Package version in the package menu."
443 :type 'natnum
444 :version "28.1")
445
446(defcustom package-status-column-width 12
447 "Column width for the Package status in the package menu."
448 :type 'natnum
449 :version "28.1")
450
451(defcustom package-archive-column-width 8
452 "Column width for the Package archive in the package menu."
453 :type 'natnum
454 :version "28.1")
455
456
457;;; `package-desc' object definition
458;; This is the struct used internally to represent packages.
459;; Functions that deal with packages should generally take this object
460;; as an argument. In some situations (e.g. commands that query the
461;; user) it makes sense to take the package name as a symbol instead,
462;; but keep in mind there could be multiple `package-desc's with the
463;; same name.
464
465(define-inline package-vc-p (pkg-desc)
466 "Return non-nil if PKG-DESC is a VC package."
467 (inline-letevals (pkg-desc)
468 (inline-quote (eq (package-desc-kind ,pkg-desc) 'vc))))
469
470(defun package--from-builtin (bi-desc)
471 "Create a `package-desc' object from BI-DESC.
472BI-DESC should be a `package--bi-desc' object."
473 (package-desc-create :name (pop bi-desc)
474 :version (package--bi-desc-version bi-desc)
475 :summary (package--bi-desc-summary bi-desc)
476 :dir 'builtin))
477
478;; Pseudo fields.
479;;;###autoload
480(defun package-version-join (vlist)
481 "Return the version string corresponding to the list VLIST.
482This is, approximately, the inverse of `version-to-list'.
483\(Actually, it returns only one of the possible inverses, since
484`version-to-list' is a many-to-one operation.)"
485 (if (null vlist)
486 ""
487 (let ((str-list (list "." (int-to-string (car vlist)))))
488 (dolist (num (cdr vlist))
489 (cond
490 ((>= num 0)
491 (push (int-to-string num) str-list)
492 (push "." str-list))
493 ((< num -4)
494 (error "Invalid version list `%s'" vlist))
495 (t
496 ;; pre, or beta, or alpha
497 (cond ((equal "." (car str-list))
498 (pop str-list))
499 ((not (string-match "[0-9]+" (car str-list)))
500 (error "Invalid version list `%s'" vlist)))
501 (push (cond ((= num -1) "pre")
502 ((= num -2) "beta")
503 ((= num -3) "alpha")
504 ((= num -4) "snapshot"))
505 str-list))))
506 (if (equal "." (car str-list))
507 (pop str-list))
508 (apply #'concat (nreverse str-list)))))
509
510;;;###autoload
511(defun package-desc-full-name (pkg-desc)
512 "Return full name of package-desc object PKG-DESC.
513This is the name of the package with its version appended."
514 (if (package-vc-p pkg-desc)
515 (symbol-name (package-desc-name pkg-desc))
516 (format "%s-%s"
517 (package-desc-name pkg-desc)
518 (package-version-join (package-desc-version pkg-desc)))))
519
520(defun package-desc-suffix (pkg-desc)
521 "Return file-name extension of package-desc object PKG-DESC.
522Depending on the `package-desc-kind' of PKG-DESC, this is one of:
523
524 \\='single - \".el\"
525 \\='tar - \".tar\"
526 \\='dir - \"\"
527
528Signal an error if the kind is none of the above."
529 (pcase (package-desc-kind pkg-desc)
530 ('single ".el")
531 ('tar ".tar")
532 ('dir "")
533 (kind (error "Unknown package kind: %s" kind))))
534
535(defun package-desc--keywords (pkg-desc)
536 "Return keywords of package-desc object PKG-DESC.
537These keywords come from the foo-pkg.el file, and in general
538corresponds to the keywords in the \"Keywords\" header of the
539package."
540 (let ((keywords (cdr (assoc :keywords (package-desc-extras pkg-desc)))))
541 (if (eq (car-safe keywords) 'quote)
542 (nth 1 keywords)
543 keywords)))
544
545(defun package-desc-priority (pkg-desc)
546 "Return the priority of the archive of package-desc object PKG-DESC."
547 (package-archive-priority (package-desc-archive pkg-desc)))
548
549(defun package--parse-elpaignore (pkg-desc)
550 "Return a list of regular expressions to match files ignored by PKG-DESC."
551 (let* ((pkg-dir (file-name-as-directory (package-desc-dir pkg-desc)))
552 (ignore (expand-file-name ".elpaignore" pkg-dir))
553 files)
554 (when (file-exists-p ignore)
555 (with-temp-buffer
556 (insert-file-contents ignore)
557 (goto-char (point-min))
558 (while (not (eobp))
559 (push (wildcard-to-regexp
560 (let ((line (buffer-substring
561 (line-beginning-position)
562 (line-end-position))))
563 (file-name-concat pkg-dir (string-trim-left line "/"))))
564 files)
565 (forward-line)))
566 files)))
567
568(cl-defstruct (package--bi-desc
569 (:constructor package-make-builtin (version summary))
570 (:type vector))
571 "Package descriptor format used in finder-inf.el and package--builtins."
572 version
573 reqs
574 summary)
575
576
577;;; Installed packages
578
579;; The following functions are called on each installed package by
580;; `package-load-all-descriptors', which ultimately populates the
581;; `package-alist' variable.
582
583(declare-function package-vc-version "package-vc" (pkg))
584
585(defun package-process-define-package (exp)
586 "Process define-package expression EXP and push it to `package-alist'.
587EXP should be a form read from a foo-pkg.el file.
588Convert EXP into a `package-desc' object using the
589`package-desc-from-define' constructor before pushing it to
590`package-alist'.
591
592If there already exists a package by the same name in
593`package-alist', insert this object there such that the packages
594are sorted with the highest version first."
595 (when (eq (car-safe exp) 'define-package)
596 (let* ((new-pkg-desc (apply #'package-desc-from-define (cdr exp)))
597 (name (package-desc-name new-pkg-desc))
598 (version (package-desc-version new-pkg-desc))
599 (old-pkgs (assq name package-alist)))
600 (if (null old-pkgs)
601 ;; If there's no old package, just add this to `package-alist'.
602 (push (list name new-pkg-desc) package-alist)
603 ;; If there is, insert the new package at the right place in the list.
604 (while
605 (if (and (cdr old-pkgs)
606 (version-list-< version
607 (package-desc-version (cadr old-pkgs))))
608 (setq old-pkgs (cdr old-pkgs))
609 (push new-pkg-desc (cdr old-pkgs))
610 nil)))
611 new-pkg-desc)))
612
613(declare-function package-vc-commit "package-vc" (pkg))
614
615(defun define-package ( _name-string _version-string
616 &optional _docstring _requirements
617 &rest _extra-properties)
618 "Define a new package.
619NAME-STRING is the name of the package, as a string.
620VERSION-STRING is the version of the package, as a string.
621DOCSTRING is a short description of the package, a string.
622REQUIREMENTS is a list of dependencies on other packages.
623 Each requirement is of the form (OTHER-PACKAGE OTHER-VERSION),
624 where OTHER-VERSION is a string.
625
626EXTRA-PROPERTIES is currently unused."
627 (declare (obsolete nil "29.1") (indent defun))
628 (error "Don't call me!"))
629
630(defun package--active-built-in-p (package)
631 "Return non-nil if the built-in version of PACKAGE is used.
632If the built-in version of PACKAGE is used and PACKAGE is
633also available for installation from an archive, it is an
634indication that PACKAGE was never upgraded to any newer
635version from the archive."
636 (and (not (assq (cond
637 ((package-desc-p package)
638 (package-desc-name package))
639 ((stringp package) (intern package))
640 ((symbolp package) package)
641 ((error "Unknown package format: %S" package)))
642 (package--alist)))
643 (package-built-in-p package)))
644
645(defsubst package--library-stem (file)
646 (catch 'done
647 (let (result)
648 (dolist (suffix (get-load-suffixes) file)
649 (setq result (string-trim file nil suffix))
650 (unless (equal file result)
651 (throw 'done result))))))
652
653;;;###autoload
654(defun package--reload-previously-loaded (pkg-desc &optional warn)
655 "Force reimportation of files in PKG-DESC already present in `load-history'.
656New editions of files contain macro definitions and
657redefinitions, the overlooking of which would cause
658byte-compilation of the new package to fail.
659If WARN is a string, display a warning (using WARN as a format string)
660before reloading the files. WARN must have two %-sequences
661corresponding to package name (a symbol) and a list of files loaded (as
662sexps)."
663 (with-demoted-errors "Error in package--load-files-for-activation: %s"
664 (let* (result
665 (dir (package-desc-dir pkg-desc))
666 ;; A previous implementation would skip `dir' itself.
667 ;; However, in normal use reloading from the same directory
668 ;; never happens anyway, while in certain cases external to
669 ;; Emacs a package in the same directory not necessary
670 ;; stays byte-identical, e.g. during development. Just
671 ;; don't special-case `dir'.
672 (effective-path (or (bound-and-true-p find-library-source-path)
673 load-path))
674 (files (directory-files-recursively dir "\\`[^\\.].*\\.el\\'"))
675 (history (mapcar #'file-truename
676 (cl-remove-if-not #'stringp
677 (mapcar #'car load-history)))))
678 (dolist (file files)
679 (when-let* ((library (package--library-stem
680 (file-relative-name file dir)))
681 (canonical (locate-library library nil effective-path))
682 (truename (file-truename canonical))
683 ;; Normally, all files in a package are compiled by
684 ;; now, but don't assume that. E.g. different
685 ;; versions can add or remove `no-byte-compile'.
686 (altname (if (string-suffix-p ".el" truename)
687 (replace-regexp-in-string
688 "\\.el\\'" ".elc" truename t)
689 (replace-regexp-in-string
690 "\\.elc\\'" ".el" truename t)))
691 (found (or (member truename history)
692 (and (not (string= altname truename))
693 (member altname history))))
694 (recent-index (length found)))
695 (unless (equal (file-name-base library)
696 (format "%s-autoloads" (package-desc-name pkg-desc)))
697 (push (cons (expand-file-name library dir) recent-index) result))))
698 (when (and result warn)
699 (display-warning 'package
700 (format warn (package-desc-name pkg-desc)
701 (mapcar #'car result))))
702 (mapc (lambda (c) (load (car c) nil t))
703 (sort result (lambda (x y) (< (cdr x) (cdr y))))))))
704
705
706;;; Installation -- Local operations
707;; This section contains a variety of features regarding installing a
708;; package to/from disk. This includes autoload generation,
709;; unpacking, compiling, as well as defining a package from the
710;; current buffer.
711
712;;;; Unpacking
713(defvar tar-parse-info)
714(declare-function tar-untar-buffer "tar-mode" ())
715(declare-function tar-header-name "tar-mode" (tar-header) t)
716(declare-function tar-header-link-type "tar-mode" (tar-header) t)
717
718(defun package-untar-buffer (dir)
719 "Untar the current buffer.
720This uses `tar-untar-buffer' from Tar mode. All files should
721untar into a directory named DIR; otherwise, signal an error."
722 (tar-mode)
723 (unwind-protect
724 (progn
725 ;; Make sure everything extracts into DIR.
726 (let ((regexp (concat "\\`" (regexp-quote (expand-file-name dir)) "/"))
727 (case-fold-search (file-name-case-insensitive-p dir)))
728 (dolist (tar-data tar-parse-info)
729 (let ((name (expand-file-name (tar-header-name tar-data))))
730 (or (string-match regexp name)
731 ;; Tarballs created by some utilities don't list
732 ;; directories with a trailing slash (Bug#13136).
733 (and (string-equal (expand-file-name dir) name)
734 (eq (tar-header-link-type tar-data) 5))
735 (error "Package does not untar cleanly into directory %s/"
736 dir)))))
737 (tar-untar-buffer))
738 (fundamental-mode))) ; free auxiliary tar-mode data
739
740(defun package--alist-to-plist-args (alist)
741 (mapcar #'macroexp-quote
742 (apply #'nconc
743 (mapcar (lambda (pair) (list (car pair) (cdr pair))) alist))))
744
745(declare-function dired-get-marked-files "dired")
746
747(defun package-unpack (pkg-desc)
748 "Install the contents of the current buffer as a package."
749 (let* ((name (package-desc-name pkg-desc))
750 (dirname (package-desc-full-name pkg-desc))
751 (pkg-dir (expand-file-name dirname package-user-dir)))
752 (pcase (package-desc-kind pkg-desc)
753 ('dir
754 (make-directory pkg-dir t)
755 (let ((file-list
756 (or (and (derived-mode-p 'dired-mode)
757 (dired-get-marked-files nil 'marked))
758 (directory-files-recursively default-directory "" nil))))
759 (dolist (source-file file-list)
760 (let ((target (expand-file-name
761 (file-relative-name source-file default-directory)
762 pkg-dir)))
763 (make-directory (file-name-directory target) t)
764 (copy-file source-file target t)))
765 ;; Now that the files have been installed, this package is
766 ;; indistinguishable from a `tar' or a `single'. Let's make
767 ;; things simple by ensuring we're one of them.
768 (setf (package-desc-kind pkg-desc)
769 (if (length> file-list 1) 'tar 'single))))
770 ('tar
771 (make-directory package-user-dir t)
772 (let* ((default-directory (file-name-as-directory package-user-dir)))
773 (package-untar-buffer dirname)))
774 ('single
775 (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir)))
776 (make-directory pkg-dir t)
777 (package--write-file-no-coding el-file)))
778 (kind (error "Unknown package kind: %S" kind)))
779 (package--make-autoloads-and-stuff pkg-desc pkg-dir)
780 ;; Update package-alist.
781 (let ((new-desc (package-load-descriptor pkg-dir)))
782 (unless (equal (package-desc-full-name new-desc)
783 (package-desc-full-name pkg-desc))
784 (error "The retrieved package (`%s') doesn't match what the archive offered (`%s')"
785 (package-desc-full-name new-desc) (package-desc-full-name pkg-desc)))
786 ;; Activation has to be done before compilation, so that if we're
787 ;; upgrading and macros have changed we load the new definitions
788 ;; before compiling.
789 (when (package-activate-1 new-desc :reload :deps)
790 ;; FIXME: Compilation should be done as a separate, optional, step.
791 ;; E.g. for multi-package installs, we should first install all packages
792 ;; and then compile them.
793 (package--compile new-desc)
794 (when package-native-compile
795 (package--native-compile-async new-desc))
796 ;; After compilation, load again any files loaded by
797 ;; `activate-1', so that we use the byte-compiled definitions.
798 (package--reload-previously-loaded new-desc)))
799 pkg-dir))
800
801(defun package-generate-description-file (pkg-desc pkg-file)
802 "Create the foo-pkg.el file PKG-FILE for single-file package PKG-DESC."
803 (let* ((name (package-desc-name pkg-desc)))
804 (let ((print-level nil)
805 (print-quoted t)
806 (print-length nil))
807 (write-region
808 (concat
809 ";;; Generated package description from "
810 (replace-regexp-in-string "-pkg\\.el\\'" ".el"
811 (file-name-nondirectory pkg-file))
812 " -*- no-byte-compile: t -*-\n"
813 (prin1-to-string
814 (nconc
815 (list 'define-package
816 (symbol-name name)
817 (package-version-join (package-desc-version pkg-desc))
818 (package-desc-summary pkg-desc)
819 (let ((requires (package-desc-reqs pkg-desc)))
820 (list 'quote
821 ;; Turn version lists into string form.
822 (mapcar
823 (lambda (elt)
824 (list (car elt)
825 (package-version-join (cadr elt))))
826 requires))))
827 (package--alist-to-plist-args
828 (package-desc-extras pkg-desc))))
829 "\n")
830 nil pkg-file nil 'silent))))
831
832
833;;;; Autoload
834(declare-function autoload-rubric "autoload" (file &optional type feature))
835
836(defun package-autoload-ensure-default-file (file)
837 "Make sure that the autoload file FILE exists and if not create it."
838 (declare (obsolete nil "29.1"))
839 (unless (file-exists-p file)
840 (require 'autoload)
841 (let ((coding-system-for-write 'utf-8-emacs-unix))
842 (with-suppressed-warnings ((obsolete autoload-rubric))
843 (write-region (autoload-rubric file "package" nil)
844 nil file nil 'silent))))
845 file)
846
847(defvar autoload-timestamps)
848(defvar version-control)
849
850(defun package-generate-autoloads (name pkg-dir)
851 "Generate autoloads in PKG-DIR for package named NAME."
852 (let* ((auto-name (format "%s-autoloads.el" name))
853 ;;(ignore-name (concat name "-pkg.el"))
854 (output-file (expand-file-name auto-name pkg-dir))
855 ;; We don't need 'em, and this makes the output reproducible.
856 (autoload-timestamps nil)
857 (backup-inhibited t)
858 (version-control 'never))
859 (loaddefs-generate
860 pkg-dir output-file nil
861 (prin1-to-string
862 '(add-to-list
863 'load-path
864 ;; Add the directory that will contain the autoload file to
865 ;; the load path. We don't hard-code `pkg-dir', to avoid
866 ;; issues if the package directory is moved around.
867 ;; `loaddefs-generate' has code to do this for us, but it's
868 ;; not currently exposed. (Bug#63625)
869 (or (and load-file-name
870 (directory-file-name
871 (file-name-directory load-file-name)))
872 (car load-path)))))
873 (let ((buf (find-buffer-visiting output-file)))
874 (when buf (kill-buffer buf)))
875 auto-name))
876
877(defun package--make-autoloads-and-stuff (pkg-desc pkg-dir)
878 "Generate autoloads, description file, etc., for PKG-DESC installed at PKG-DIR."
879 (package-generate-autoloads (package-desc-name pkg-desc) pkg-dir)
880 (let ((desc-file (expand-file-name (package--description-file pkg-dir)
881 pkg-dir)))
882 (unless (file-exists-p desc-file)
883 (package-generate-description-file pkg-desc desc-file)))
884 ;; FIXME: Create foo.info and dir file from foo.texi?
885 )
886
887;;;; Compilation
888(defvar warning-minimum-level)
889(defvar byte-compile-ignore-files)
890(defun package--compile (pkg-desc)
891 "Byte-compile installed package PKG-DESC.
892This assumes that `pkg-desc' has already been activated with
893`package-activate-1'."
894 (let ((byte-compile-ignore-files (package--parse-elpaignore pkg-desc))
895 (warning-minimum-level :error)
896 (load-path load-path))
897 (byte-recompile-directory (package-desc-dir pkg-desc) 0 t)))
898
899(defun package--native-compile-async (pkg-desc)
900 "Native compile installed package PKG-DESC asynchronously.
901This assumes that `pkg-desc' has already been activated with
902`package-activate-1'."
903 (when (native-comp-available-p)
904 (let ((warning-minimum-level :error))
905 (native-compile-async (package-desc-dir pkg-desc) t))))
906
907;;;; Inferring package from current buffer
908(defun package-read-from-string (str)
909 "Read a Lisp expression from STR.
910Signal an error if the entire string was not used."
911 (pcase-let ((`(,expr . ,offset) (read-from-string str)))
912 (condition-case ()
913 ;; The call to `ignore' suppresses a compiler warning.
914 (progn (ignore (read-from-string str offset))
915 (error "Can't read whole string"))
916 (end-of-file expr))))
917
918(declare-function lm-header "lisp-mnt" (header))
919(declare-function lm-package-requires "lisp-mnt" (&optional file))
920(declare-function lm-package-version "lisp-mnt" (&optional file))
921(declare-function lm-website "lisp-mnt" (&optional file))
922(declare-function lm-keywords-list "lisp-mnt" (&optional file))
923(declare-function lm-maintainers "lisp-mnt" (&optional file))
924(declare-function lm-authors "lisp-mnt" (&optional file))
925
926(defun package-buffer-info ()
927 "Return a `package-desc' describing the package in the current buffer.
928
929If the buffer does not contain a conforming package, signal an
930error. If there is a package, narrow the buffer to the file's
931boundaries."
932 (goto-char (point-min))
933 (unless (re-search-forward "^;;; \\([^ ]*\\)\\.el ---[ \t]*\\(.*?\\)[ \t]*\\(-\\*-.*-\\*-[ \t]*\\)?$" nil t)
934 (error "Package lacks a file header"))
935 (let ((file-name (match-string-no-properties 1))
936 (desc (match-string-no-properties 2)))
937 (require 'lisp-mnt)
938 (let* ((version-info (lm-package-version))
939 (pkg-version (package-strip-rcs-id version-info))
940 (keywords (lm-keywords-list))
941 (website (lm-website)))
942 (unless pkg-version
943 (if version-info
944 (error "Unrecognized package version: %s" version-info)
945 (error "Package lacks a \"Version\" or \"Package-Version\" header")))
946 (package-desc-from-define
947 file-name pkg-version desc
948 (lm-package-requires)
949 :kind 'single
950 :url website
951 :keywords keywords
952 :maintainer
953 ;; For backward compatibility, use a single cons-cell if
954 ;; there's only one maintainer (the most common case).
955 (let ((maints (lm-maintainers))) (if (cdr maints) maints (car maints)))
956 :authors (lm-authors)))))
957
958(defun package--read-pkg-desc (kind)
959 "Read a `define-package' form in current buffer.
960Return the pkg-desc, with desc-kind set to KIND."
961 (goto-char (point-min))
962 (let* ((pkg-def-parsed (read (current-buffer)))
963 (pkg-desc
964 (when (eq (car pkg-def-parsed) 'define-package)
965 (apply #'package-desc-from-define
966 (append (cdr pkg-def-parsed))))))
967 (when pkg-desc
968 (setf (package-desc-kind pkg-desc) kind)
969 pkg-desc)))
970
971(declare-function tar-get-file-descriptor "tar-mode" (file))
972(declare-function tar--extract "tar-mode" (descriptor))
973
974(defun package-tar-file-info ()
975 "Find package information for a tar file.
976The return result is a `package-desc'."
977 (cl-assert (derived-mode-p 'tar-mode))
978 (let* ((dir-name (named-let loop
979 ((filename (tar-header-name (car tar-parse-info))))
980 (let ((dirname (file-name-directory filename)))
981 ;; The first file can be in a subdir: look for the top.
982 (if dirname (loop (directory-file-name dirname))
983 (file-name-as-directory filename)))))
984 (desc-file (package--description-file dir-name))
985 (tar-desc (tar-get-file-descriptor (concat dir-name desc-file))))
986 (unless tar-desc
987 (error "No package descriptor file found"))
988 (with-current-buffer (tar--extract tar-desc)
989 (unwind-protect
990 (or (package--read-pkg-desc 'tar)
991 (error "Can't find define-package in %s"
992 (tar-header-name tar-desc)))
993 (kill-buffer (current-buffer))))))
994
995(defun package-dir-info ()
996 "Find package information for a directory.
997The return result is a `package-desc'."
998 (cl-assert (derived-mode-p 'dired-mode))
999 (let* ((desc-file (package--description-file default-directory)))
1000 (if (file-readable-p desc-file)
1001 (with-temp-buffer
1002 (insert-file-contents desc-file)
1003 (package--read-pkg-desc 'dir))
1004 (catch 'found
1005 (let ((files (or (and (derived-mode-p 'dired-mode)
1006 (dired-get-marked-files nil 'marked))
1007 (directory-files default-directory t "\\.el\\'" t))))
1008 ;; We sort the file names by length, to ensure that we check
1009 ;; shorter file names first, as these are more likely to
1010 ;; contain the package metadata.
1011 (dolist (file (sort files :key #'length))
1012 ;; The file may be a link to a nonexistent file; e.g., a
1013 ;; lock file.
1014 (when (file-exists-p file)
1015 (with-temp-buffer
1016 (insert-file-contents file)
1017 ;; When we find the file with the data,
1018 (when-let* ((info (ignore-errors (package-buffer-info))))
1019 (setf (package-desc-kind info) 'dir)
1020 (throw 'found info))))))
1021 (error "No .el files with package headers in `%s'" default-directory)))))
1022
1023
1024;;; Communicating with Archives
1025;; Set of low-level functions for communicating with archives and
1026;; signature checking.
1027
1028(defun package--write-file-no-coding (file-name)
1029 "Write file FILE-NAME without encoding using coding system."
1030 (let ((buffer-file-coding-system 'no-conversion))
1031 (write-region (point-min) (point-max) file-name nil 'silent)))
1032
1033(declare-function url-http-file-exists-p "url-http" (url))
1034
1035(defun package--archive-file-exists-p (location file)
1036 "Return t if FILE exists in remote LOCATION."
1037 (let ((http (string-match "\\`https?:" location)))
1038 (if http
1039 (progn
1040 (require 'url-http)
1041 (url-http-file-exists-p (concat location file)))
1042 (file-exists-p (expand-file-name file location)))))
1043
1044(declare-function epg-make-context "epg"
1045 (&optional protocol armor textmode include-certs
1046 cipher-algorithm
1047 digest-algorithm
1048 compress-algorithm))
1049(declare-function epg-verify-string "epg" ( context signature
1050 &optional signed-text))
1051(declare-function epg-context-result-for "epg" (context name))
1052(declare-function epg-signature-status "epg" (signature) t)
1053(declare-function epg-signature-to-string "epg" (signature))
1054
1055(defun package--display-verify-error (context sig-file)
1056 "Show error details with CONTEXT for failed verification of SIG-FILE.
1057The details are shown in a new buffer called \"*Error\"."
1058 (unless (equal (epg-context-error-output context) "")
1059 (with-output-to-temp-buffer "*Error*"
1060 (with-current-buffer standard-output
1061 (if (epg-context-result-for context 'verify)
1062 (insert (format "Failed to verify signature %s:\n" sig-file)
1063 (mapconcat #'epg-signature-to-string
1064 (epg-context-result-for context 'verify)
1065 "\n"))
1066 (insert (format "Error while verifying signature %s:\n" sig-file)))
1067 (insert "\nCommand output:\n" (epg-context-error-output context))))))
1068
1069(defmacro package--with-work-buffer (location file &rest body)
1070 "Run BODY in a buffer containing the contents of FILE at LOCATION.
1071LOCATION is the base location of a package archive, and should be
1072one of the URLs (or file names) specified in `package-archives'.
1073FILE is the name of a file relative to that base location.
1074
1075This macro retrieves FILE from LOCATION into a temporary buffer,
1076and evaluates BODY while that buffer is current. This work
1077buffer is killed afterwards. Return the last value in BODY."
1078 (declare (indent 2) (debug t)
1079 (obsolete package--with-response-buffer "25.1"))
1080 `(with-temp-buffer
1081 (if (string-match-p "\\`https?:" ,location)
1082 (url-insert-file-contents (concat ,location ,file))
1083 (unless (file-name-absolute-p ,location)
1084 (error "Archive location %s is not an absolute file name"
1085 ,location))
1086 (insert-file-contents (expand-file-name ,file ,location)))
1087 ,@body))
1088
1089(cl-defmacro package--with-response-buffer (url &rest body &key async file error-form noerror &allow-other-keys)
1090 "Access URL and run BODY in a buffer containing the response.
1091Point is after the headers when BODY runs.
1092FILE, if provided, is added to URL.
1093URL can be a local file name, which must be absolute.
1094ASYNC, if non-nil, runs the request asynchronously.
1095ERROR-FORM is run only if a connection error occurs. If NOERROR
1096is non-nil, don't propagate connection errors (does not apply to
1097errors signaled by ERROR-FORM or by BODY).
1098
1099\(fn URL &key ASYNC FILE ERROR-FORM NOERROR &rest BODY)"
1100 (declare (indent defun) (debug (sexp body)))
1101 (while (keywordp (car body))
1102 (setq body (cdr (cdr body))))
1103 `(package--with-response-buffer-1 ,url (lambda () ,@body)
1104 :file ,file
1105 :async ,async
1106 :error-function (lambda () ,error-form)
1107 :noerror ,noerror))
1108
1109(defmacro package--unless-error (body &rest before-body)
1110 (declare (debug t) (indent 1))
1111 (let ((err (make-symbol "err")))
1112 `(with-temp-buffer
1113 (set-buffer-multibyte nil)
1114 (when (condition-case ,err
1115 (progn ,@before-body t)
1116 (error (funcall error-function)
1117 (unless noerror
1118 (signal (car ,err) (cdr ,err)))))
1119 (funcall ,body)))))
1120
1121(cl-defun package--with-response-buffer-1 (url body &key async file error-function noerror &allow-other-keys)
1122 (if (string-match-p "\\`https?:" url)
1123 (let ((url (url-expand-file-name file url)))
1124 (if async
1125 (package--unless-error #'ignore
1126 (url-retrieve
1127 url
1128 (lambda (status)
1129 (let ((b (current-buffer)))
1130 (require 'url-handlers)
1131 (package--unless-error body
1132 (when-let* ((er (plist-get status :error)))
1133 (error "Error retrieving: %s %S" url er))
1134 (with-current-buffer b
1135 (goto-char (point-min))
1136 (unless (search-forward-regexp "^\r?\n\r?" nil t)
1137 (error "Error retrieving: %s %S"
1138 url "incomprehensible buffer")))
1139 (url-insert b)
1140 (kill-buffer b)
1141 (goto-char (point-min)))))
1142 nil
1143 'silent))
1144 (package--unless-error body
1145 ;; Copy&pasted from url-insert-file-contents,
1146 ;; except it calls `url-insert' because we want the contents
1147 ;; literally (but there's no url-insert-file-contents-literally).
1148 (let ((buffer (url-retrieve-synchronously url)))
1149 (unless buffer (signal 'file-error (list url "No Data")))
1150 (when (fboundp 'url-http--insert-file-helper)
1151 ;; XXX: This is HTTP/S specific and should be moved
1152 ;; to url-http instead. See bug#17549.
1153 (url-http--insert-file-helper buffer url))
1154 (url-insert buffer)
1155 (kill-buffer buffer)
1156 (goto-char (point-min))))))
1157 (package--unless-error body
1158 (unless (file-name-absolute-p url)
1159 (error "Location %s is not a url nor an absolute file name" url))
1160 (insert-file-contents-literally (expand-file-name file url)))))
1161
1162(define-error 'bad-signature "Failed to verify signature")
1163
1164(defun package--check-signature-content (content string &optional sig-file)
1165 "Check signature CONTENT against STRING.
1166SIG-FILE is the name of the signature file, used when signaling
1167errors."
1168 (let ((context (epg-make-context 'OpenPGP)))
1169 (when package-gnupghome-dir
1170 (setf (epg-context-home-directory context) package-gnupghome-dir))
1171 (condition-case error
1172 (epg-verify-string context content string)
1173 (error (package--display-verify-error context sig-file)
1174 (signal 'bad-signature error)))
1175 (let (good-signatures had-fatal-error)
1176 ;; The .sig file may contain multiple signatures. Success if one
1177 ;; of the signatures is good.
1178 (dolist (sig (epg-context-result-for context 'verify))
1179 (if (eq (epg-signature-status sig) 'good)
1180 (push sig good-signatures)
1181 ;; If `package-check-signature' is allow-unsigned, don't
1182 ;; signal error when we can't verify signature because of
1183 ;; missing public key. Other errors are still treated as
1184 ;; fatal (bug#17625).
1185 (unless (and (eq (package-check-signature) 'allow-unsigned)
1186 (eq (epg-signature-status sig) 'no-pubkey))
1187 (setq had-fatal-error t))))
1188 (when (or (null good-signatures)
1189 (and (eq (package-check-signature) 'all)
1190 had-fatal-error))
1191 (package--display-verify-error context sig-file)
1192 (signal 'bad-signature (list sig-file)))
1193 good-signatures)))
1194
1195(defun package--check-signature (location file &optional string async callback unwind)
1196 "Check signature of the current buffer.
1197Download the signature file from LOCATION by appending \".sig\"
1198to FILE.
1199GnuPG keyring location depends on `package-gnupghome-dir'.
1200STRING is the string to verify, it defaults to `buffer-string'.
1201If ASYNC is non-nil, the download of the signature file is
1202done asynchronously.
1203
1204If the signature does not verify, signal an error.
1205If the signature is verified and CALLBACK was provided, `funcall'
1206CALLBACK with the list of good signatures as argument (the list
1207can be empty).
1208If no signatures file is found, and `package-check-signature' is
1209`allow-unsigned', call CALLBACK with a nil argument.
1210Otherwise, an error is signaled.
1211
1212UNWIND, if provided, is a function to be called after everything
1213else, even if an error is signaled."
1214 (let ((sig-file (concat file ".sig"))
1215 (string (or string (buffer-string))))
1216 (package--with-response-buffer location :file sig-file
1217 :async async :noerror t
1218 ;; Connection error is assumed to mean "no sig-file".
1219 :error-form (let ((allow-unsigned
1220 (eq (package-check-signature) 'allow-unsigned)))
1221 (when (and callback allow-unsigned)
1222 (funcall callback nil))
1223 (when unwind (funcall unwind))
1224 (unless allow-unsigned
1225 (error "Unsigned file `%s' at %s" file location)))
1226 ;; OTOH, an error here means "bad signature", which we never
1227 ;; suppress. (Bug#22089)
1228 (unwind-protect
1229 (let ((sig (package--check-signature-content
1230 (buffer-substring (point) (point-max))
1231 string sig-file)))
1232 (when callback (funcall callback sig))
1233 sig)
1234 (when unwind (funcall unwind))))))
1235
1236;;; Packages on Archives
1237;; The following variables store information about packages available
1238;; from archives. The most important of these is
1239;; `package-archive-contents' which is initially populated by the
1240;; function `package-read-all-archive-contents' from a cache on disk.
1241;; The `package-initialize' command is also closely related to this
1242;; section, but it has its own section.
1243
1244(defconst package-archive-version 1
1245 "Version number of the package archive understood by package.el.
1246Lower version numbers than this will probably be understood as well.")
1247
1248;; We don't prime the cache since it tends to get out of date.
1249(defvar package-archive-contents nil
1250 "Cache of the contents of all archives in `package-archives'.
1251This is an alist mapping package names (symbols) to
1252non-empty lists of `package-desc' structures.")
1253(put 'package-archive-contents 'risky-local-variable t)
1254
1255(defvar package--compatibility-table nil
1256 "Hash table connecting package names to their compatibility.
1257Each key is a symbol, the name of a package.
1258
1259The value is either nil, representing an incompatible package, or
1260a version list, representing the highest compatible version of
1261that package which is available.
1262
1263A package is considered incompatible if it requires an Emacs
1264version higher than the one being used. To check for package
1265\(in)compatibility, don't read this table directly, use
1266`package--incompatible-p' which also checks dependencies.")
1267
1268(defun package--build-compatibility-table ()
1269 "Build `package--compatibility-table' with `package--mapc'."
1270 ;; Initialize the list of built-ins.
1271 (require 'finder-inf nil t)
1272 ;; Build compat table.
1273 (setq package--compatibility-table (make-hash-table :test 'eq))
1274 (package--mapc #'package--add-to-compatibility-table))
1275
1276(defun package--add-to-compatibility-table (pkg)
1277 "If PKG is compatible (without dependencies), add to the compatibility table.
1278PKG is a package-desc object.
1279Only adds if its version is higher than what's already stored in
1280the table."
1281 (unless (package--incompatible-p pkg 'shallow)
1282 (let* ((name (package-desc-name pkg))
1283 (version (or (package-desc-version pkg) '(0)))
1284 (table-version (gethash name package--compatibility-table)))
1285 (when (or (not table-version)
1286 (version-list-< table-version version))
1287 (puthash name version package--compatibility-table)))))
1288
1289;; Package descriptor objects used inside the "archive-contents" file.
1290;; Changing this defstruct implies changing the format of the
1291;; "archive-contents" files.
1292(cl-defstruct (package--ac-desc
1293 (:constructor package-make-ac-desc (version reqs summary kind extras))
1294 (:copier nil)
1295 (:type vector))
1296 version reqs summary kind extras)
1297
1298(defun package--append-to-alist (pkg-desc alist)
1299 "Append an entry for PKG-DESC to the start of ALIST and return it.
1300This entry takes the form (`package-desc-name' PKG-DESC).
1301
1302If ALIST already has an entry with this name, destructively add
1303PKG-DESC to the cdr of this entry instead, sorted by version
1304number."
1305 (let* ((name (package-desc-name pkg-desc))
1306 (priority-version (package-desc-priority-version pkg-desc))
1307 (existing-packages (assq name alist)))
1308 (if (not existing-packages)
1309 (cons (list name pkg-desc)
1310 alist)
1311 (while (if (and (cdr existing-packages)
1312 (version-list-< priority-version
1313 (package-desc-priority-version
1314 (cadr existing-packages))))
1315 (setq existing-packages (cdr existing-packages))
1316 (push pkg-desc (cdr existing-packages))
1317 nil))
1318 alist)))
1319
1320(defun package--add-to-archive-contents (package archive)
1321 "Add the PACKAGE from the given ARCHIVE if necessary.
1322PACKAGE should have the form (NAME . PACKAGE--AC-DESC).
1323Also, add the originating archive to the `package-desc' structure."
1324 (let* ((name (car package))
1325 (version (package--ac-desc-version (cdr package)))
1326 (pkg-desc
1327 (package-desc-create
1328 :name name
1329 :version version
1330 :reqs (package--ac-desc-reqs (cdr package))
1331 :summary (package--ac-desc-summary (cdr package))
1332 :kind (package--ac-desc-kind (cdr package))
1333 :archive archive
1334 :extras (and (> (length (cdr package)) 4)
1335 ;; Older archive-contents files have only 4
1336 ;; elements here.
1337 (package--ac-desc-extras (cdr package)))))
1338 (pinned-to-archive (assoc name package-pinned-packages)))
1339 ;; Skip entirely if pinned to another archive.
1340 (when (not (and pinned-to-archive
1341 (not (equal (cdr pinned-to-archive) archive))))
1342 (setq package-archive-contents
1343 (package--append-to-alist pkg-desc package-archive-contents)))))
1344
1345(defun package--read-archive-file (file)
1346 "Read cached archive FILE data, if it exists.
1347Return the data from the file, or nil if the file does not exist.
1348If the archive version is too new, signal an error."
1349 (let ((filename (expand-file-name file package-user-dir)))
1350 (when (file-exists-p filename)
1351 (with-temp-buffer
1352 (let ((coding-system-for-read 'utf-8))
1353 (insert-file-contents filename))
1354 (let ((contents (read (current-buffer))))
1355 (if (> (car contents) package-archive-version)
1356 (error "Package archive version %d is higher than %d"
1357 (car contents) package-archive-version))
1358 (cdr contents))))))
1359
1360(defun package-read-archive-contents (archive)
1361 "Read cached archive file for ARCHIVE.
1362If successful, set or update the variable `package-archive-contents'.
1363ARCHIVE should be a string matching the name of a package archive
1364in the variable `package-archives'.
1365If the archive version is too new, signal an error."
1366 ;; Version 1 of 'archive-contents' is identical to our internal
1367 ;; representation.
1368 (let* ((contents-file (format "archives/%s/archive-contents" archive))
1369 (contents (package--read-archive-file contents-file)))
1370 (when contents
1371 (dolist (package contents)
1372 (if package
1373 (package--add-to-archive-contents package archive)
1374 (lwarn '(package refresh) :warning
1375 "Ignoring nil package on `%s' package archive" archive))))))
1376
1377(defvar package--old-archive-priorities nil
1378 "Store currently used `package-archive-priorities'.
1379This is the value of `package-archive-priorities' last time
1380`package-read-all-archive-contents' was called. It can be used
1381by arbitrary functions to decide whether it is necessary to call
1382it again.")
1383
1384(defvar package-read-archive-hook (list #'package-read-archive-contents)
1385 "List of functions to call to read the archive contents.
1386Each function must take an optional argument, a symbol indicating
1387what archive to read in. The symbol ought to be a key in
1388`package-archives'.")
1389
1390(defun package-read-all-archive-contents ()
1391 "Read cached archive file for all archives in `package-archives'.
1392If successful, set or update `package-archive-contents'."
1393 (setq package-archive-contents nil)
1394 (setq package--old-archive-priorities package-archive-priorities)
1395 (dolist (archive package-archives)
1396 (run-hook-with-args 'package-read-archive-hook (car archive))))
1397
1398
1399;;;; Package Initialize
1400;; A bit of a milestone. This brings together some of the above
1401;; sections and populates all relevant lists of packages from contents
1402;; available on disk.
1403
1404(defvar package--initialized nil
1405 "Non-nil if `package-initialize' has been run.")
1406
1407;;;###autoload
1408(defun package-initialize (&optional no-activate)
1409 "Load Emacs Lisp packages, and activate them.
1410The variable `package-load-list' controls which packages to load.
1411If optional arg NO-ACTIVATE is non-nil, don't activate packages.
1412
1413It is not necessary to adjust `load-path' or `require' the
1414individual packages after calling `package-initialize' -- this is
1415taken care of by `package-initialize'.
1416
1417If `package-initialize' is called twice during Emacs startup,
1418signal a warning, since this is a bad idea except in highly
1419advanced use cases. To suppress the warning, remove the
1420superfluous call to `package-initialize' from your init-file. If
1421you have code which must run before `package-initialize', put
1422that code in the early init-file."
1423 (interactive)
1424 (when (and package--initialized (not after-init-time))
1425 (lwarn '(package reinitialization) :warning
1426 "Unnecessary call to `package-initialize' in init file"))
1427 (setq package-alist nil)
1428 (package-load-all-descriptors)
1429 (package-read-all-archive-contents)
1430 (setq package--initialized t)
1431 (unless no-activate
1432 (package-activate-all))
1433 ;; This uses `package--mapc' so it must be called after
1434 ;; `package--initialized' is t.
1435 (package--build-compatibility-table))
1436
1437
1438;;;; Populating `package-archive-contents' from archives
1439;; This subsection populates the variables listed above from the
1440;; actual archives, instead of from a local cache.
1441
1442(defvar package--downloads-in-progress nil
1443 "List of in-progress asynchronous downloads.")
1444
1445(declare-function epg-import-keys-from-file "epg" (context keys))
1446
1447;;;###autoload
1448(defun package-import-keyring (&optional file)
1449 "Import keys from FILE."
1450 (interactive "fFile: ")
1451 (setq file (expand-file-name file))
1452 (let ((context (epg-make-context 'OpenPGP)))
1453 (when package-gnupghome-dir
1454 (with-file-modes #o700
1455 (make-directory package-gnupghome-dir t))
1456 (setf (epg-context-home-directory context) package-gnupghome-dir))
1457 (message "Importing %s..." (file-name-nondirectory file))
1458 (epg-import-keys-from-file context file)
1459 (message "Importing %s...done" (file-name-nondirectory file))))
1460
1461(defvar package--post-download-archives-hook nil
1462 "Hook run after the archive contents are downloaded.
1463Don't run this hook directly. It is meant to be run as part of
1464`package--update-downloads-in-progress'.")
1465(put 'package--post-download-archives-hook 'risky-local-variable t)
1466
1467(defun package--update-downloads-in-progress (entry)
1468 "Remove ENTRY from `package--downloads-in-progress'.
1469Once it's empty, run `package--post-download-archives-hook'."
1470 ;; Keep track of the downloading progress.
1471 (setq package--downloads-in-progress
1472 (remove entry package--downloads-in-progress))
1473 ;; If this was the last download, run the hook.
1474 (unless package--downloads-in-progress
1475 (package-read-all-archive-contents)
1476 (package--build-compatibility-table)
1477 ;; We message before running the hook, so the hook can give
1478 ;; messages as well.
1479 (message "Package refresh done")
1480 (run-hooks 'package--post-download-archives-hook)))
1481
1482(defun package--download-one-archive (archive file &optional async)
1483 "Retrieve an archive file FILE from ARCHIVE, and cache it.
1484ARCHIVE should be a cons cell of the form (NAME . LOCATION),
1485similar to an entry in `package-alist'. Save the cached copy to
1486\"archives/NAME/FILE\" in `package-user-dir'."
1487 ;; The downloaded archive contents will be read as part of
1488 ;; `package--update-downloads-in-progress'.
1489 (when async
1490 (cl-pushnew (cons archive file) package--downloads-in-progress
1491 :test #'equal))
1492 (package--with-response-buffer (cdr archive) :file file
1493 :async async
1494 :error-form (package--update-downloads-in-progress (cons archive file))
1495 (let* ((location (cdr archive))
1496 (name (car archive))
1497 (content (buffer-string))
1498 (dir (expand-file-name (concat "archives/" name) package-user-dir))
1499 (local-file (expand-file-name file dir)))
1500 (when (listp (read content))
1501 (make-directory dir t)
1502 (if (or (not (package-check-signature))
1503 (member name package-unsigned-archives))
1504 ;; If we don't care about the signature, save the file and
1505 ;; we're done.
1506 (progn
1507 (cl-assert (not enable-multibyte-characters))
1508 (let ((coding-system-for-write 'binary))
1509 (write-region content nil local-file nil 'silent))
1510 (package--update-downloads-in-progress (cons archive file)))
1511 ;; If we care, check it (perhaps async) and *then* write the file.
1512 (package--check-signature
1513 location file content async
1514 ;; This function will be called after signature checking.
1515 (lambda (&optional good-sigs)
1516 (cl-assert (not enable-multibyte-characters))
1517 (let ((coding-system-for-write 'binary))
1518 (write-region content nil local-file nil 'silent))
1519 ;; Write out good signatures into archive-contents.signed file.
1520 (when good-sigs
1521 (write-region (mapconcat #'epg-signature-to-string good-sigs "\n")
1522 nil (concat local-file ".signed") nil 'silent)))
1523 (lambda () (package--update-downloads-in-progress (cons archive file)))))))))
1524
1525(defun package--download-and-read-archives (&optional async)
1526 "Download descriptions of all `package-archives' and read them.
1527Populate `package-archive-contents' with the result.
1528
1529If optional argument ASYNC is non-nil, perform the downloads
1530asynchronously."
1531 (dolist (archive package-archives)
1532 (condition-case-unless-debug err
1533 (package--download-one-archive archive "archive-contents" async)
1534 (error (message "Failed to download `%s' archive: %s"
1535 (car archive)
1536 (error-message-string err))))))
1537
1538(defvar package-refresh-contents-hook (list #'package--download-and-read-archives)
1539 "List of functions to call to refresh the package archive.
1540Each function may take an optional argument indicating that the
1541operation ought to be executed asynchronously.")
1542
1543;;;###autoload
1544(defun package-refresh-contents (&optional async)
1545 "Download descriptions of all configured ELPA packages.
1546For each archive configured in the variable `package-archives',
1547inform Emacs about the latest versions of all packages it offers,
1548and make them available for download.
1549Optional argument ASYNC specifies whether to perform the
1550downloads in the background. This is always the case when the command
1551is invoked interactively."
1552 (interactive (list t))
1553 (when async
1554 (message "Refreshing package contents..."))
1555 (unless (file-exists-p package-user-dir)
1556 (make-directory package-user-dir t))
1557 (let ((default-keyring (expand-file-name "package-keyring.gpg"
1558 data-directory))
1559 (inhibit-message (or inhibit-message async)))
1560 (when (and (package-check-signature) (file-exists-p default-keyring))
1561 (condition-case-unless-debug error
1562 (package-import-keyring default-keyring)
1563 (error (message "Cannot import default keyring: %s"
1564 (error-message-string error))))))
1565 (run-hook-with-args 'package-refresh-contents-hook async))
1566
1567
1568;;; Dependency Management
1569;; Calculating the full transaction necessary for an installation,
1570;; keeping track of which packages were installed strictly as
1571;; dependencies, and determining which packages cannot be removed
1572;; because they are dependencies.
1573
1574(defun package-compute-transaction (packages requirements &optional seen)
1575 "Return a list of packages to be installed, including PACKAGES.
1576PACKAGES should be a list of `package-desc'.
1577
1578REQUIREMENTS should be a list of additional requirements; each
1579element in this list should have the form (PACKAGE VERSION-LIST),
1580where PACKAGE is a package name and VERSION-LIST is the required
1581version of that package.
1582
1583This function recursively computes the requirements of the
1584packages in REQUIREMENTS, and returns a list of all the packages
1585that must be installed. Packages that are already installed are
1586not included in this list.
1587
1588SEEN is used internally to detect infinite recursion."
1589 ;; FIXME: We really should use backtracking to explore the whole
1590 ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1
1591 ;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0:
1592 ;; the current code might fail to see that it could install foo by using the
1593 ;; older bar-1.3).
1594 (dolist (elt requirements)
1595 (let* ((next-pkg (car elt))
1596 (next-version (cadr elt))
1597 (already ()))
1598 (dolist (pkg packages)
1599 (if (eq next-pkg (package-desc-name pkg))
1600 (setq already pkg)))
1601 (when already
1602 (if (version-list-<= next-version (package-desc-version already))
1603 ;; `next-pkg' is already in `packages', but its position there
1604 ;; means it might be installed too late: remove it from there, so
1605 ;; we re-add it (along with its dependencies) at an earlier place
1606 ;; below (bug#16994).
1607 (if (memq already seen) ;Avoid inf-loop on dependency cycles.
1608 (message "Dependency cycle going through %S"
1609 (package-desc-full-name already))
1610 (setq packages (delq already packages))
1611 (setq already nil))
1612 (error "Need package `%s-%s', but only %s is being installed"
1613 next-pkg (package-version-join next-version)
1614 (package-version-join (package-desc-version already)))))
1615 (cond
1616 (already nil)
1617 ((package-installed-p next-pkg next-version) nil)
1618
1619 (t
1620 ;; A package is required, but not installed. It might also be
1621 ;; blocked via `package-load-list'.
1622 (let ((pkg-descs (cdr (assq next-pkg package-archive-contents)))
1623 (found nil)
1624 (found-something nil)
1625 (problem nil))
1626 (while (and pkg-descs (not found))
1627 (let* ((pkg-desc (pop pkg-descs))
1628 (version (package-desc-version pkg-desc))
1629 (disabled (package-disabled-p next-pkg version)))
1630 (cond
1631 ((version-list-< version next-version)
1632 ;; pkg-descs is sorted by priority, not version, so
1633 ;; don't error just yet.
1634 (unless found-something
1635 (setq found-something (package-version-join version))))
1636 (disabled
1637 (unless problem
1638 (setq problem
1639 (if (stringp disabled)
1640 (format-message
1641 "Package `%s' held at version %s, but version %s required"
1642 next-pkg disabled
1643 (package-version-join next-version))
1644 (format-message "Required package `%s' is disabled"
1645 next-pkg)))))
1646 (t (setq found pkg-desc)))))
1647 (unless found
1648 (cond
1649 (problem (error "%s" problem))
1650 (found-something
1651 (error "Need package `%s-%s', but only %s is available"
1652 next-pkg (package-version-join next-version)
1653 found-something))
1654 (t
1655 (if (eq next-pkg 'emacs)
1656 (error "This package requires Emacs version %s"
1657 (package-version-join next-version))
1658 (error (if (not next-version)
1659 (format "Package `%s' is unavailable" next-pkg)
1660 (format "Package `%s' (version %s) is unavailable"
1661 next-pkg (package-version-join next-version))))))))
1662 (setq packages
1663 (package-compute-transaction (cons found packages)
1664 (package-desc-reqs found)
1665 (cons found seen))))))))
1666 packages)
1667
1668(defun package--find-non-dependencies ()
1669 "Return a list of installed packages which are not dependencies.
1670Finds all packages in `package-alist' which are not dependencies
1671of any other packages.
1672Used to populate `package-selected-packages'."
1673 (let ((dep-list
1674 (delete-dups
1675 (apply #'append
1676 (mapcar (lambda (p) (mapcar #'car (package-desc-reqs (cadr p))))
1677 package-alist)))))
1678 (cl-loop for p in package-alist
1679 for name = (car p)
1680 unless (memq name dep-list)
1681 collect name)))
1682
1683(defun package--save-selected-packages (&optional value)
1684 "Set and save `package-selected-packages' to VALUE."
1685 (when (or value after-init-time)
1686 ;; It is valid to set it to nil, for example when the last package
1687 ;; is uninstalled. But it shouldn't be done at init time, to
1688 ;; avoid overwriting configurations that haven't yet been loaded.
1689 (setq package-selected-packages (sort value #'string<)))
1690 (if after-init-time
1691 (customize-save-variable 'package-selected-packages package-selected-packages)
1692 (add-hook 'after-init-hook #'package--save-selected-packages)))
1693
1694(defun package--user-selected-p (pkg)
1695 "Return non-nil if PKG is a package was installed by the user.
1696PKG is a package name.
1697This looks into `package-selected-packages', populating it first
1698if it is still empty."
1699 (unless (consp package-selected-packages)
1700 (package--save-selected-packages (package--find-non-dependencies)))
1701 (memq pkg package-selected-packages))
1702
1703(defun package--get-deps (pkgs)
1704 (let ((seen '()))
1705 (while pkgs
1706 (let ((pkg (pop pkgs)))
1707 (if (memq pkg seen)
1708 nil ;; Done already!
1709 (let ((pkg-desc (cadr (assq pkg package-alist))))
1710 (when pkg-desc
1711 (push pkg seen)
1712 (setq pkgs (append (mapcar #'car (package-desc-reqs pkg-desc))
1713 pkgs)))))))
1714 seen))
1715
1716(defun package--user-installed-p (package)
1717 "Return non-nil if PACKAGE is a user-installed package.
1718PACKAGE is the package name, a symbol. Check whether the package
1719was installed into `package-user-dir' where we assume to have
1720control over."
1721 (let* ((pkg-desc (cadr (assq package package-alist)))
1722 (dir (package-desc-dir pkg-desc)))
1723 (file-in-directory-p dir package-user-dir)))
1724
1725(defun package--removable-packages ()
1726 "Return a list of names of packages no longer needed.
1727These are packages which are neither contained in
1728`package-selected-packages' nor a dependency of one that is."
1729 (let ((needed (package--get-deps package-selected-packages)))
1730 (cl-loop for p in (mapcar #'car package-alist)
1731 unless (or (memq p needed)
1732 ;; Do not auto-remove external packages.
1733 (not (package--user-installed-p p)))
1734 collect p)))
1735
1736(defun package--used-elsewhere-p (pkg-desc &optional pkg-list all)
1737 "Non-nil if PKG-DESC is a dependency of a package in PKG-LIST.
1738Return the first package found in PKG-LIST of which PKG is a
1739dependency. If ALL is non-nil, return all such packages instead.
1740
1741When not specified, PKG-LIST defaults to `package-alist'
1742with PKG-DESC entry removed."
1743 (unless (string= (package-desc-status pkg-desc) "obsolete")
1744 (let* ((pkg (package-desc-name pkg-desc))
1745 (alist (or pkg-list
1746 (remove (assq pkg package-alist)
1747 package-alist))))
1748 (if all
1749 (cl-loop for p in alist
1750 if (assq pkg (package-desc-reqs (cadr p)))
1751 collect (cadr p))
1752 (cl-loop for p in alist thereis
1753 (and (assq pkg (package-desc-reqs (cadr p)))
1754 (cadr p)))))))
1755
1756(defun package--sort-deps-in-alist (package only)
1757 "Return a list of dependencies for PACKAGE sorted by dependency.
1758PACKAGE is included as the first element of the returned list.
1759ONLY is an alist associating package names to package objects.
1760Only these packages will be in the return value and their cdrs are
1761destructively set to nil in ONLY."
1762 (let ((out))
1763 (dolist (dep (package-desc-reqs package))
1764 (when-let* ((cell (assq (car dep) only))
1765 (dep-package (cdr-safe cell)))
1766 (setcdr cell nil)
1767 (setq out (append (package--sort-deps-in-alist dep-package only)
1768 out))))
1769 (cons package out)))
1770
1771(defun package--sort-by-dependence (package-list)
1772 "Return PACKAGE-LIST sorted by dependence.
1773That is, any element of the returned list is guaranteed to not
1774directly depend on any elements that come before it.
1775
1776PACKAGE-LIST is a list of `package-desc' objects.
1777Indirect dependencies are guaranteed to be returned in order only
1778if all the in-between dependencies are also in PACKAGE-LIST."
1779 (let ((alist (mapcar (lambda (p) (cons (package-desc-name p) p)) package-list))
1780 out-list)
1781 (dolist (cell alist out-list)
1782 ;; `package--sort-deps-in-alist' destructively changes alist, so
1783 ;; some cells might already be empty. We check this here.
1784 (when-let* ((pkg-desc (cdr cell)))
1785 (setcdr cell nil)
1786 (setq out-list
1787 (append (package--sort-deps-in-alist pkg-desc alist)
1788 out-list))))))
1789
1790
1791;;; Installation Functions
1792;; As opposed to the previous section (which listed some underlying
1793;; functions necessary for installation), this one contains the actual
1794;; functions that install packages. The package itself can be
1795;; installed in a variety of ways (archives, buffer, file), but
1796;; requirements (dependencies) are always satisfied by looking in
1797;; `package-archive-contents'.
1798;;
1799;; If Emacs installs a package from a package archive, it might create
1800;; some files in addition to the package's contents. For example:
1801;;
1802;; - If the package archive provides a non-trivial long description for
1803;; some package in "PACKAGE-readme.txt", Emacs stores it in a file
1804;; named "README-elpa" in the package's content directory, unless the
1805;; package itself provides such a file.
1806;;
1807;; - If a package archive provides package signatures, Emacs stores
1808;; information on the signatures in files named "NAME-VERSION.signed"
1809;; below directory `package-user-dir'.
1810
1811(defun package-archive-base (desc)
1812 "Return the package described by DESC."
1813 (cdr (assoc (package-desc-archive desc) package-archives)))
1814
1815(defun package-install-from-archive (pkg-desc)
1816 "Download and install a package defined by PKG-DESC."
1817 ;; This won't happen, unless the archive is doing something wrong.
1818 (when (eq (package-desc-kind pkg-desc) 'dir)
1819 (error "Can't install directory package from archive"))
1820 (let* ((location (package-archive-base pkg-desc))
1821 (file (concat (package-desc-full-name pkg-desc)
1822 (package-desc-suffix pkg-desc))))
1823 (package--with-response-buffer location :file file
1824 (if (or (not (package-check-signature))
1825 (member (package-desc-archive pkg-desc)
1826 package-unsigned-archives))
1827 ;; If we don't care about the signature, unpack and we're
1828 ;; done.
1829 (let ((save-silently t))
1830 (package-unpack pkg-desc))
1831 ;; If we care, check it and *then* write the file.
1832 (let ((content (buffer-string)))
1833 (package--check-signature
1834 location file content nil
1835 ;; This function will be called after signature checking.
1836 (lambda (&optional good-sigs)
1837 ;; Signature checked, unpack now.
1838 (with-temp-buffer ;FIXME: Just use the previous current-buffer.
1839 (set-buffer-multibyte nil)
1840 (cl-assert (not (multibyte-string-p content)))
1841 (insert content)
1842 (let ((save-silently t))
1843 (package-unpack pkg-desc)))
1844 ;; Here the package has been installed successfully, mark it as
1845 ;; signed if appropriate.
1846 (when good-sigs
1847 ;; Write out good signatures into NAME-VERSION.signed file.
1848 (write-region (mapconcat #'epg-signature-to-string good-sigs "\n")
1849 nil
1850 (expand-file-name
1851 (concat (package-desc-full-name pkg-desc) ".signed")
1852 package-user-dir)
1853 nil 'silent)
1854 ;; Update the old pkg-desc which will be shown on the description buffer.
1855 (setf (package-desc-signed pkg-desc) t)
1856 ;; Update the new (activated) pkg-desc as well.
1857 (when-let* ((pkg-descs (cdr (assq (package-desc-name pkg-desc)
1858 package-alist))))
1859 (setf (package-desc-signed (car pkg-descs)) t))))))))
1860 ;; fetch a backup of the readme file from the server. Slot `dir' is
1861 ;; not yet available in PKG-DESC, so cobble that up.
1862 (let* ((dirname (package-desc-full-name pkg-desc))
1863 (pkg-dir (expand-file-name dirname package-user-dir))
1864 (readme (expand-file-name "README-elpa" pkg-dir)))
1865 (unless (file-readable-p readme)
1866 (package--with-response-buffer (package-archive-base pkg-desc)
1867 :file (format "%s-readme.txt" (package-desc-name pkg-desc))
1868 :noerror t
1869 ;; do not write empty or whitespace-only readmes to give
1870 ;; `package--get-description' a chance to find another readme
1871 (unless (save-excursion
1872 (goto-char (point-min))
1873 (looking-at-p "[[:space:]]*\\'"))
1874 (write-region nil nil readme)))))))
1875
1876;;;###autoload
1877(defun package-installed-p (package &optional min-version)
1878 "Return non-nil if PACKAGE, of MIN-VERSION or newer, is installed.
1879If PACKAGE is a symbol, it is the package name and MIN-VERSION
1880should be a version list.
1881
1882If PACKAGE is a `package-desc' object, MIN-VERSION is ignored."
1883 (cond
1884 ((package-desc-p package)
1885 (let ((dir (package-desc-dir package)))
1886 (and (stringp dir)
1887 (file-exists-p dir))))
1888 ((and (not package--initialized)
1889 (null min-version)
1890 package-activated-list)
1891 ;; We used the quickstart: make it possible to use package-installed-p
1892 ;; even before package is fully initialized.
1893 (or
1894 (memq package package-activated-list)
1895 ;; Also check built-in packages.
1896 (package-built-in-p package min-version)))
1897 (t
1898 (or
1899 (let ((pkg-descs (cdr (assq package (package--alist)))))
1900 (and pkg-descs
1901 (version-list-<= min-version
1902 (package-desc-version (car pkg-descs)))))
1903 ;; Also check built-in packages.
1904 (package-built-in-p package min-version)))))
1905
1906(defun package-download-transaction (packages)
1907 "Download and install all the packages in PACKAGES.
1908PACKAGES should be a list of `package-desc'.
1909This function assumes that all package requirements in
1910PACKAGES are satisfied, i.e. that PACKAGES is computed
1911using `package-compute-transaction'."
1912 (mapc #'package-install-from-archive packages))
1913
1914(defun package--archives-initialize ()
1915 "Make sure the list of installed and remote packages are initialized."
1916 (unless package--initialized
1917 (package-initialize t))
1918 (unless package-archive-contents
1919 (package-refresh-contents)))
1920
1921(defcustom package-install-upgrade-built-in nil
1922 "Non-nil means that built-in packages can be upgraded via a package archive.
1923If disabled, then `package-install' will raise an error when trying to
1924replace a built-in package with a (possibly newer) version from a
1925package archive."
1926 :type 'boolean
1927 :version "29.1")
1928
1929;;;###autoload
1930(defun package-install (pkg &optional dont-select)
1931 "Install the package PKG.
1932
1933PKG can be a `package-desc', or a symbol naming one of the available
1934packages in an archive in `package-archives'.
1935
1936Mark the installed package as selected by adding it to
1937`package-selected-packages'.
1938
1939When called from Lisp and optional argument DONT-SELECT is
1940non-nil, install the package but do not add it to
1941`package-selected-packages'.
1942
1943If PKG is a `package-desc' and it is already installed, don't try
1944to install it but still mark it as selected.
1945
1946If the command is invoked with a prefix argument, it will allow
1947upgrading of built-in packages, as if `package-install-upgrade-built-in'
1948had been enabled."
1949 (interactive
1950 (progn
1951 ;; Initialize the package system to get the list of package
1952 ;; symbols for completion.
1953 (package--archives-initialize)
1954 (list (intern (completing-read
1955 "Install package: "
1956 package-archive-contents
1957 nil t))
1958 nil)))
1959 (cl-check-type pkg (or symbol package-desc))
1960 (package--archives-initialize)
1961 (add-hook 'post-command-hook #'package-menu--post-refresh)
1962 (let ((name (if (package-desc-p pkg)
1963 (package-desc-name pkg)
1964 pkg)))
1965 (when (or (and package-install-upgrade-built-in
1966 (package--active-built-in-p pkg))
1967 (package-installed-p pkg))
1968 (user-error "`%s' is already installed" name))
1969 (unless (or dont-select (package--user-selected-p name))
1970 (package--save-selected-packages
1971 (cons name package-selected-packages)))
1972 (when (and (or current-prefix-arg package-install-upgrade-built-in)
1973 (package--active-built-in-p pkg))
1974 (setq pkg (or (cadr (assq name package-archive-contents)) pkg)))
1975 (if-let* ((transaction
1976 (if (package-desc-p pkg)
1977 (unless (package-installed-p pkg)
1978 (package-compute-transaction (list pkg)
1979 (package-desc-reqs pkg)))
1980 (package-compute-transaction () (list (list pkg))))))
1981 (progn
1982 (package-download-transaction transaction)
1983 (package--quickstart-maybe-refresh)
1984 (message "Package `%s' installed." name)))))
1985
1986
1987(declare-function package-vc-upgrade "package-vc" (pkg))
1988
1989;;;###autoload
1990(defun package-upgrade (name)
1991 "Upgrade package NAME if a newer version exists.
1992
1993NAME should be a symbol."
1994 (interactive
1995 (list (intern (completing-read
1996 "Upgrade package: "
1997 (package--upgradeable-packages t) nil t))))
1998 (cl-check-type name symbol)
1999 (let* ((pkg-desc (cadr (assq name package-alist)))
2000 (package-install-upgrade-built-in (not pkg-desc)))
2001 ;; `pkg-desc' will be nil when the package is an "active built-in".
2002 (if (and pkg-desc (package-vc-p pkg-desc))
2003 (package-vc-upgrade pkg-desc)
2004 (when pkg-desc
2005 (package-delete pkg-desc 'force 'dont-unselect))
2006 (package-install name
2007 ;; An active built-in has never been "selected"
2008 ;; before. Mark it as installed explicitly.
2009 (and pkg-desc 'dont-select)))))
2010
2011(defun package--upgradeable-packages (&optional include-builtins)
2012 ;; Initialize the package system to get the list of package
2013 ;; symbols for completion.
2014 (package--archives-initialize)
2015 (mapcar
2016 #'car
2017 (seq-filter
2018 (lambda (elt)
2019 (or (let ((available
2020 (assq (car elt) package-archive-contents)))
2021 (and available
2022 (or (and
2023 include-builtins
2024 (not (package-desc-version (cadr elt))))
2025 (version-list-<
2026 (package-desc-version (cadr elt))
2027 (package-desc-version (cadr available))))))
2028 (package-vc-p (cadr elt))))
2029 (if include-builtins
2030 (append package-alist
2031 (mapcan
2032 (lambda (elt)
2033 (when (not (assq (car elt) package-alist))
2034 (list (list (car elt) (package--from-builtin elt)))))
2035 package--builtins))
2036 package-alist))))
2037
2038;;;###autoload
2039(defun package-upgrade-all (&optional query)
2040 "Refresh package list and upgrade all packages.
2041If QUERY, ask the user before upgrading packages. When called
2042interactively, QUERY is always true.
2043
2044Currently, packages which are part of the Emacs distribution are
2045not upgraded by this command. To enable upgrading such a package
2046using this command, first upgrade the package to a newer version
2047from ELPA by either using `\\[package-upgrade]' or
2048`\\<package-menu-mode-map>\\[package-menu-mark-install]' after `\\[list-packages]'."
2049 (interactive (list (not noninteractive)))
2050 (package-refresh-contents)
2051 (let ((upgradeable (package--upgradeable-packages package-install-upgrade-built-in)))
2052 (if (not upgradeable)
2053 (message "No packages to upgrade")
2054 (when (and query
2055 (not (yes-or-no-p
2056 (if (length= upgradeable 1)
2057 "One package to upgrade. Do it? "
2058 (format "%s packages to upgrade. Do it?"
2059 (length upgradeable))))))
2060 (user-error "Upgrade aborted"))
2061 (mapc #'package-upgrade upgradeable))))
2062
2063(defun package--dependencies (pkg)
2064 "Return a list of all transitive dependencies of PKG.
2065If PKG is a package descriptor, the return value is a list of
2066package descriptors. If PKG is a symbol designating a package,
2067the return value is a list of symbols designating packages."
2068 (when-let* ((desc (if (package-desc-p pkg) pkg
2069 (cadr (assq pkg package-archive-contents)))))
2070 ;; Can we have circular dependencies? Assume "nope".
2071 (let ((all (named-let more ((pkg-desc desc))
2072 (let (deps)
2073 (dolist (req (package-desc-reqs pkg-desc))
2074 (setq deps (nconc
2075 (catch 'found
2076 (dolist (p (apply #'append (mapcar #'cdr (package--alist))))
2077 (when (and (string= (car req) (package-desc-name p))
2078 (version-list-<= (cadr req) (package-desc-version p)))
2079 (throw 'found (more p)))))
2080 deps)))
2081 (delete-dups (cons pkg-desc deps))))))
2082 (remq pkg (mapcar (if (package-desc-p pkg) #'identity #'package-desc-name) all)))))
2083
2084(defun package-strip-rcs-id (str)
2085 "Strip RCS version ID from the version string STR.
2086If the result looks like a dotted numeric version, return it.
2087Otherwise return nil."
2088 (when str
2089 (when (string-match "\\`[ \t]*[$]Revision:[ \t]+" str)
2090 (setq str (substring str (match-end 0))))
2091 (let ((l (version-to-list str)))
2092 ;; Don't return `str' but (package-version-join (version-to-list str))
2093 ;; to make sure we use a "canonical name"!
2094 (if l (package-version-join l)))))
2095
2096(declare-function lm-website "lisp-mnt" (&optional file))
2097
2098;;;###autoload
2099(defun package-install-from-buffer ()
2100 "Install a package from the current buffer.
2101The current buffer is assumed to be a single .el or .tar file or
2102a directory. These must follow the packaging guidelines (see
2103info node `(elisp)Packaging').
2104
2105Specially, if current buffer is a directory, the -pkg.el
2106description file is not mandatory, in which case the information
2107is derived from the main .el file in the directory. Using Dired,
2108you can restrict what files to install by marking specific files.
2109
2110Downloads and installs required packages as needed."
2111 (interactive)
2112 (let* ((pkg-desc
2113 (cond
2114 ((derived-mode-p 'dired-mode)
2115 ;; This is the only way a package-desc object with a `dir'
2116 ;; desc-kind can be created. Such packages can't be
2117 ;; uploaded or installed from archives, they can only be
2118 ;; installed from local buffers or directories.
2119 (package-dir-info))
2120 ((derived-mode-p 'tar-mode)
2121 (package-tar-file-info))
2122 (t
2123 ;; Package headers should be parsed from decoded text
2124 ;; (see Bug#48137) where possible.
2125 (if (and (eq buffer-file-coding-system 'no-conversion)
2126 buffer-file-name)
2127 (let* ((package-buffer (current-buffer))
2128 (decoding-system
2129 (car (find-operation-coding-system
2130 'insert-file-contents
2131 (cons buffer-file-name
2132 package-buffer)))))
2133 (with-temp-buffer
2134 (insert-buffer-substring package-buffer)
2135 (decode-coding-region (point-min) (point-max)
2136 decoding-system)
2137 (package-buffer-info)))
2138
2139 (save-excursion
2140 (package-buffer-info))))))
2141 (name (package-desc-name pkg-desc)))
2142 ;; Download and install the dependencies.
2143 (let* ((requires (package-desc-reqs pkg-desc))
2144 (transaction (package-compute-transaction nil requires)))
2145 (package-download-transaction transaction))
2146 ;; Install the package itself.
2147 (package-unpack pkg-desc)
2148 (unless (package--user-selected-p name)
2149 (package--save-selected-packages
2150 (cons name package-selected-packages)))
2151 (package--quickstart-maybe-refresh)
2152 pkg-desc))
2153
2154;;;###autoload
2155(defun package-install-file (file)
2156 "Install a package from FILE.
2157The file can either be a tar file, an Emacs Lisp file, or a
2158directory."
2159 (interactive "fPackage file name: ")
2160 (with-temp-buffer
2161 (if (file-directory-p file)
2162 (progn
2163 (setq default-directory file)
2164 (dired-mode))
2165 (insert-file-contents-literally file)
2166 (set-visited-file-name file)
2167 (set-buffer-modified-p nil)
2168 (when (string-match "\\.tar\\'" file) (tar-mode)))
2169 (unwind-protect
2170 (package-install-from-buffer)
2171 (fundamental-mode)))) ; free auxiliary data
2172
2173;;;###autoload
2174(defun package-install-selected-packages (&optional noconfirm)
2175 "Ensure packages in `package-selected-packages' are installed.
2176If some packages are not installed, propose to install them.
2177
2178If optional argument NOCONFIRM is non-nil, or when invoked with a prefix
2179argument, don't ask for confirmation to install packages."
2180 (interactive "P")
2181 (package--archives-initialize)
2182 ;; We don't need to populate `package-selected-packages' before
2183 ;; using here, because the outcome is the same either way (nothing
2184 ;; gets installed).
2185 (if (not package-selected-packages)
2186 (message "`package-selected-packages' is empty, nothing to install")
2187 (let* ((not-installed (seq-remove #'package-installed-p package-selected-packages))
2188 (available (seq-filter (lambda (p) (assq p package-archive-contents)) not-installed))
2189 (difference (- (length not-installed) (length available))))
2190 (cond
2191 (available
2192 (when (or noconfirm
2193 (y-or-n-p
2194 (format "Packages to install: %d (%s), proceed? "
2195 (length available)
2196 (mapconcat #'symbol-name available " "))))
2197 (mapc (lambda (p) (package-install p 'dont-select)) available)))
2198 ((> difference 0)
2199 (message (substitute-command-keys
2200 "Packages that are not available: %d (the rest is already \
2201installed), maybe you need to \\[package-refresh-contents]")
2202 difference))
2203 (t
2204 (message "All your packages are already installed"))))))
2205
2206
2207;;; Package Deletion
2208
2209(defun package--newest-p (pkg)
2210 "Return non-nil if PKG is the newest package with its name."
2211 (equal (cadr (assq (package-desc-name pkg) package-alist))
2212 pkg))
2213
2214(declare-function comp-el-to-eln-filename "comp.c")
2215(defvar package-vc-repository-store)
2216(defun package--delete-directory (dir)
2217 "Delete PKG-DESC directory DIR recursively.
2218Clean-up the corresponding .eln files if Emacs is native
2219compiled, and remove the DIR from `load-path'."
2220 (setq load-path (cl-remove-if (lambda (s) (file-in-directory-p s dir))
2221 load-path))
2222 (when (featurep 'native-compile)
2223 (cl-loop
2224 for file in (directory-files-recursively dir
2225 ;; Exclude lockfiles
2226 (rx bos (or (and "." (not "#")) (not ".")) (* nonl) ".el" eos))
2227 do (comp-clean-up-stale-eln (comp-el-to-eln-filename file))))
2228 (if (file-symlink-p (directory-file-name dir))
2229 (delete-file (directory-file-name dir))
2230 (delete-directory dir t)))
2231
2232
2233(defun package-delete (pkg-desc &optional force nosave)
2234 "Delete package PKG-DESC.
2235
2236Argument PKG-DESC is the full description of the package, for example as
2237obtained by `package-get-descriptor'. Interactively, prompt the user
2238for the package name and version.
2239
2240When package is used elsewhere as dependency of another package,
2241refuse deleting it and return an error.
2242If prefix argument FORCE is non-nil, package will be deleted even
2243if it is used elsewhere.
2244If NOSAVE is non-nil, the package is not removed from
2245`package-selected-packages'."
2246 (interactive
2247 (progn
2248 (let* ((package-table
2249 (mapcar
2250 (lambda (p) (cons (package-desc-full-name p) p))
2251 (delq nil
2252 (mapcar (lambda (p) (unless (package-built-in-p p) p))
2253 (apply #'append (mapcar #'cdr (package--alist)))))))
2254 (package-name (completing-read "Delete package: "
2255 (mapcar #'car package-table)
2256 nil t)))
2257 (list (cdr (assoc package-name package-table))
2258 current-prefix-arg nil))))
2259 (let* ((dir (package-desc-dir pkg-desc))
2260 (name (package-desc-name pkg-desc))
2261 (new-package-alist (let ((pkgs (assq name package-alist)))
2262 (if (null (remove pkg-desc (cdr pkgs)))
2263 (remq pkgs package-alist)
2264 package-alist)))
2265 pkg-used-elsewhere-by)
2266 ;; If the user is trying to delete this package, they definitely
2267 ;; don't want it marked as selected, so we remove it from
2268 ;; `package-selected-packages' even if it can't be deleted.
2269 (when (and (null nosave)
2270 (package--user-selected-p name)
2271 ;; Don't deselect if this is an older version of an
2272 ;; upgraded package.
2273 (package--newest-p pkg-desc))
2274 (package--save-selected-packages (remove name package-selected-packages)))
2275 (cond ((not (string-prefix-p (file-name-as-directory
2276 (expand-file-name package-user-dir))
2277 (expand-file-name dir)))
2278 ;; Don't delete "system" packages.
2279 (error "Package `%s' is a system package, not deleting"
2280 (package-desc-full-name pkg-desc)))
2281 ((and (null force)
2282 (setq pkg-used-elsewhere-by
2283 (let ((package-alist new-package-alist))
2284 (package--used-elsewhere-p pkg-desc)))) ;See bug#65475
2285 ;; Don't delete packages used as dependency elsewhere.
2286 (error "Package `%s' is used by `%s' as dependency, not deleting"
2287 (package-desc-full-name pkg-desc)
2288 (package-desc-name pkg-used-elsewhere-by)))
2289 (t
2290 (add-hook 'post-command-hook #'package-menu--post-refresh)
2291 (package--delete-directory dir)
2292 ;; Remove NAME-VERSION.signed and NAME-readme.txt files.
2293 ;;
2294 ;; NAME-readme.txt files are no longer created, but they
2295 ;; may be left around from an earlier install.
2296 (dolist (suffix '(".signed" "readme.txt"))
2297 (let* ((version (package-version-join (package-desc-version pkg-desc)))
2298 (file (concat (if (string= suffix ".signed")
2299 dir
2300 (substring dir 0 (- (length version))))
2301 suffix)))
2302 (when (file-exists-p file)
2303 (delete-file file))))
2304 ;; Update package-alist.
2305 (setq package-alist new-package-alist)
2306 (package--quickstart-maybe-refresh)
2307 (message "Package `%s' deleted."
2308 (package-desc-full-name pkg-desc))))))
2309
2310;;;###autoload
2311(defun package-reinstall (pkg)
2312 "Reinstall package PKG.
2313PKG should be either a symbol, the package name, or a `package-desc'
2314object."
2315 (interactive
2316 (progn
2317 (package--archives-initialize)
2318 (list (intern (completing-read
2319 "Reinstall package: "
2320 (mapcar #'symbol-name
2321 (mapcar #'car package-alist)))))))
2322 (package--archives-initialize)
2323 (package-delete
2324 (if (package-desc-p pkg) pkg (cadr (assq pkg package-alist)))
2325 'force 'nosave)
2326 (package-install pkg 'dont-select))
2327
2328;;;###autoload
2329(defun package-recompile (pkg)
2330 "Byte-compile package PKG again.
2331PKG should be either a symbol, the package name, or a `package-desc'
2332object."
2333 (interactive (list (intern (completing-read
2334 "Recompile package: "
2335 (mapcar #'symbol-name
2336 (mapcar #'car package-alist))))))
2337 (let ((pkg-desc (if (package-desc-p pkg)
2338 pkg
2339 (cadr (assq pkg package-alist)))))
2340 ;; Delete the old .elc files to ensure that we don't inadvertently
2341 ;; load them (in case they contain byte code/macros that are now
2342 ;; invalid).
2343 (dolist (elc (directory-files-recursively
2344 (package-desc-dir pkg-desc) "\\.elc\\'"))
2345 (delete-file elc))
2346 (package--compile pkg-desc)))
2347
2348;;;###autoload
2349(defun package-recompile-all ()
2350 "Byte-compile all installed packages.
2351This is meant to be used only in the case the byte-compiled files
2352are invalid due to changed byte-code, macros or the like."
2353 (interactive)
2354 (pcase-dolist (`(_ ,pkg-desc) package-alist)
2355 (with-demoted-errors "Error while recompiling: %S"
2356 (package-recompile pkg-desc))))
2357
2358;;;###autoload
2359(defun package-autoremove (&optional noconfirm)
2360 "Remove packages that are no longer needed.
2361
2362Packages that are no more needed by other packages in
2363`package-selected-packages' and their dependencies
2364will be deleted.
2365
2366If optional argument NOCONFIRM is non-nil, or when invoked with a prefix
2367argument, don't ask for confirmation to install packages."
2368 (interactive "P")
2369 ;; If `package-selected-packages' is nil, it would make no sense to
2370 ;; try to populate it here, because then `package-autoremove' will
2371 ;; do absolutely nothing.
2372 (when (or noconfirm
2373 package-selected-packages
2374 (yes-or-no-p
2375 (format-message
2376 "`package-selected-packages' is empty! Really remove ALL packages? ")))
2377 (let ((removable (package--removable-packages)))
2378 (if removable
2379 (when (or noconfirm
2380 (y-or-n-p
2381 (format "Packages to delete: %d (%s), proceed? "
2382 (length removable)
2383 (mapconcat #'symbol-name removable " "))))
2384 (mapc (lambda (p)
2385 (package-delete (cadr (assq p package-alist)) t))
2386 removable))
2387 (message "Nothing to autoremove")))))
2388
2389(defun package-isolate (packages &optional temp-init)
2390 "Start an uncustomized Emacs and only load a set of PACKAGES.
2391Interactively, prompt for PACKAGES to load, which should be specified
2392separated by commas.
2393If called from Lisp, PACKAGES should be a list of packages to load.
2394If TEMP-INIT is non-nil, or when invoked with a prefix argument,
2395the Emacs user directory is set to a temporary directory.
2396This command is intended for testing Emacs and/or the packages
2397in a clean environment."
2398 (interactive
2399 (cl-loop for p in (cl-loop for p in (package--alist) append (cdr p))
2400 unless (package-built-in-p p)
2401 collect (cons (package-desc-full-name p) p) into table
2402 finally return
2403 (list
2404 (cl-loop for c in
2405 (completing-read-multiple
2406 "Packages to isolate: " table
2407 nil t)
2408 collect (alist-get c table nil nil #'string=))
2409 current-prefix-arg)))
2410 (let* ((name (concat "package-isolate-"
2411 (mapconcat #'package-desc-full-name packages ",")))
2412 (all-packages (delete-consecutive-dups
2413 (sort (append packages (mapcan #'package--dependencies packages))
2414 (lambda (p0 p1)
2415 (string< (package-desc-name p0) (package-desc-name p1))))))
2416 initial-scratch-message package-load-list)
2417 (with-temp-buffer
2418 (insert ";; This is an isolated testing environment, with these packages enabled:\n\n")
2419 (dolist (package all-packages)
2420 (push (list (package-desc-name package)
2421 (package-version-join (package-desc-version package)))
2422 package-load-list)
2423 (insert ";; - " (package-desc-full-name package))
2424 (unless (memq package packages)
2425 (insert " (dependency)"))
2426 (insert "\n"))
2427 (insert "\n")
2428 (setq initial-scratch-message (buffer-string)))
2429 (apply #'start-process (concat "*" name "*") nil
2430 (list (expand-file-name invocation-name invocation-directory)
2431 "--quick" "--debug-init"
2432 "--init-directory" (if temp-init
2433 (make-temp-file name t)
2434 user-emacs-directory)
2435 (format "--eval=%S"
2436 `(progn
2437 (setq initial-scratch-message ,initial-scratch-message)
2438
2439 (require 'package)
2440 ,@(mapcar
2441 (lambda (dir)
2442 `(add-to-list 'package-directory-list ,dir))
2443 (cons package-user-dir package-directory-list))
2444 (setq package-load-list ',package-load-list)
2445 (package-activate-all)))))))
2446
2447
2448;;;; Package description buffer.
2449
2450;;;###autoload
2451(defun describe-package (package)
2452 "Display the full documentation of PACKAGE (a symbol)."
2453 (interactive
2454 (let* ((guess (or (function-called-at-point)
2455 (symbol-at-point))))
2456 (require 'finder-inf nil t)
2457 ;; Load the package list if necessary (but don't activate them).
2458 (unless package--initialized
2459 (package-initialize t))
2460 (let ((packages (append (mapcar #'car package-alist)
2461 (mapcar #'car package-archive-contents)
2462 (mapcar #'car package--builtins))))
2463 (unless (memq guess packages)
2464 (setq guess nil))
2465 (setq packages (mapcar #'symbol-name packages))
2466 (let ((val
2467 (completing-read (format-prompt "Describe package" guess)
2468 packages nil t nil nil (when guess
2469 (symbol-name guess)))))
2470 (list (and (> (length val) 0) (intern val)))))))
2471 (if (not (or (package-desc-p package) (and package (symbolp package))))
2472 (message "No package specified")
2473 (help-setup-xref (list #'describe-package package)
2474 (called-interactively-p 'interactive))
2475 (with-help-window (help-buffer)
2476 (with-current-buffer standard-output
2477 (describe-package-1 package)))))
2478
2479(defface package-help-section-name
2480 '((t :inherit (bold font-lock-function-name-face)))
2481 "Face used on section names in package description buffers."
2482 :version "25.1")
2483
2484(defun package--print-help-section (name &rest strings)
2485 "Print \"NAME: \", right aligned to the 13th column.
2486If more STRINGS are provided, insert them followed by a newline.
2487Otherwise no newline is inserted."
2488 (declare (indent 1))
2489 (insert (make-string (max 0 (- 11 (string-width name))) ?\s)
2490 (propertize (concat name ": ") 'font-lock-face 'package-help-section-name))
2491 (when strings
2492 (apply #'insert strings)
2493 (insert "\n")))
2494
2495(declare-function lm-commentary "lisp-mnt" (&optional file))
2496
2497(defun package--get-description (desc)
2498 "Return a string containing the long description of the package DESC.
2499The description is read from the installed package files."
2500 ;; Installed packages have nil for kind, so we look for README
2501 ;; first, then fall back to the Commentary header.
2502
2503 ;; We don’t include README.md here, because that is often the home
2504 ;; page on a site like github, and not suitable as the package long
2505 ;; description.
2506 (let ((files '("README-elpa" "README-elpa.md" "README" "README.rst" "README.org"))
2507 file
2508 (srcdir (package-desc-dir desc))
2509 result)
2510 (while (and files
2511 (not result))
2512 (setq file (pop files))
2513 (when (file-readable-p (expand-file-name file srcdir))
2514 ;; Found a README.
2515 (with-temp-buffer
2516 (insert-file-contents (expand-file-name file srcdir))
2517 (setq result (buffer-string)))))
2518
2519 (or
2520 result
2521
2522 ;; Look for Commentary header.
2523 (lm-commentary (expand-file-name
2524 (format "%s.el" (package-desc-name desc)) srcdir))
2525 "")))
2526
2527(defun package--describe-add-library-links ()
2528 "Add links to library names in package description."
2529 (while (re-search-forward "\\<\\([-[:alnum:]]+\\.el\\)\\>" nil t)
2530 (if (locate-library (match-string 1))
2531 (make-text-button (match-beginning 1) (match-end 1)
2532 'xref (match-string-no-properties 1)
2533 'help-echo "Read this file's commentary"
2534 :type 'package--finder-xref))))
2535
2536(defun describe-package-1 (pkg)
2537 "Insert the package description for PKG.
2538Helper function for `describe-package'."
2539 (require 'lisp-mnt)
2540 (let* ((desc (or
2541 (if (package-desc-p pkg) pkg)
2542 (cadr (assq pkg package-alist))
2543 (let ((built-in (assq pkg package--builtins)))
2544 (if built-in
2545 (package--from-builtin built-in)
2546 (cadr (assq pkg package-archive-contents))))))
2547 (name (if desc (package-desc-name desc) pkg))
2548 (pkg-dir (if desc (package-desc-dir desc)))
2549 (reqs (if desc (package-desc-reqs desc)))
2550 (required-by (if desc (package--used-elsewhere-p desc nil 'all)))
2551 (version (if desc (package-desc-version desc)))
2552 (archive (if desc (package-desc-archive desc)))
2553 (extras (and desc (package-desc-extras desc)))
2554 (website (cdr (assoc :url extras)))
2555 (commit (cdr (assoc :commit extras)))
2556 (keywords (if desc (package-desc--keywords desc)))
2557 (built-in (eq pkg-dir 'builtin))
2558 (installable (and archive (not built-in)))
2559 (status (if desc (package-desc-status desc) "orphan"))
2560 (incompatible-reason (package--incompatible-p desc))
2561 (signed (if desc (package-desc-signed desc)))
2562 (maintainers (or (cdr (assoc :maintainer extras))
2563 (cdr (assoc :maintainers extras))))
2564 (authors (cdr (assoc :authors extras)))
2565 (news (and-let* (pkg-dir
2566 ((not built-in))
2567 (file (expand-file-name "news" pkg-dir))
2568 ((file-regular-p file))
2569 ((file-readable-p file)))
2570 file)))
2571 (when (string= status "avail-obso")
2572 (setq status "available obsolete"))
2573 (when incompatible-reason
2574 (setq status "incompatible"))
2575 (princ (format "Package %S is %s.\n\n" name status))
2576
2577 ;; TODO: Remove the string decorations and reformat the strings
2578 ;; for future l10n.
2579 (package--print-help-section "Status")
2580 (cond (built-in
2581 (insert (propertize (capitalize status)
2582 'font-lock-face 'package-status-built-in)
2583 "."))
2584 (pkg-dir
2585 (insert (propertize (if (member status '("unsigned" "dependency"))
2586 "Installed"
2587 (capitalize status))
2588 'font-lock-face 'package-status-built-in))
2589 (insert (substitute-command-keys " in `"))
2590 (let ((dir (abbreviate-file-name
2591 (file-name-as-directory
2592 (if (file-in-directory-p pkg-dir package-user-dir)
2593 (file-relative-name pkg-dir package-user-dir)
2594 pkg-dir)))))
2595 (help-insert-xref-button dir 'help-package-def pkg-dir))
2596 (if (and (package-built-in-p name)
2597 (not (package-built-in-p name version)))
2598 (insert (substitute-command-keys
2599 "',\n shadowing a ")
2600 (propertize "built-in package"
2601 'font-lock-face 'package-status-built-in))
2602 (insert (substitute-quotes "'")))
2603 (if signed
2604 (insert ".")
2605 (insert " (unsigned)."))
2606 (when (and (package-desc-p desc)
2607 (not required-by)
2608 (member status '("unsigned" "installed")))
2609 (insert " ")
2610 (package-make-button "Delete"
2611 'action #'package-delete-button-action
2612 'package-desc desc)))
2613 (incompatible-reason
2614 (insert (propertize "Incompatible" 'font-lock-face 'font-lock-warning-face)
2615 " because it depends on ")
2616 (if (stringp incompatible-reason)
2617 (insert "Emacs " incompatible-reason ".")
2618 (insert "uninstallable packages.")))
2619 (installable
2620 (insert (capitalize status))
2621 (insert " from " (format "%s" archive))
2622 (insert " -- ")
2623 (package-make-button
2624 "Install"
2625 'action 'package-install-button-action
2626 'package-desc desc))
2627 (t (insert (capitalize status) ".")))
2628 (insert "\n")
2629 (unless (and pkg-dir (not archive)) ; Installed pkgs don't have archive.
2630 (package--print-help-section "Archive"
2631 (or archive "n/a")))
2632 (and version
2633 (package--print-help-section "Version"
2634 (package-version-join version)))
2635 (when commit
2636 (package--print-help-section "Commit" commit))
2637 (when desc
2638 (package--print-help-section "Summary"
2639 (package-desc-summary desc)))
2640
2641 (setq reqs (if desc (package-desc-reqs desc)))
2642 (when reqs
2643 (package--print-help-section "Requires")
2644 (let ((first t))
2645 (dolist (req reqs)
2646 (let* ((name (car req))
2647 (vers (cadr req))
2648 (text (format "%s-%s" (symbol-name name)
2649 (package-version-join vers)))
2650 (reason (if (and (listp incompatible-reason)
2651 (assq name incompatible-reason))
2652 " (not available)" "")))
2653 (cond (first (setq first nil))
2654 ((>= (+ 2 (current-column) (length text) (length reason))
2655 (window-width))
2656 (insert ",\n "))
2657 (t (insert ", ")))
2658 (help-insert-xref-button text 'help-package name)
2659 (insert reason)))
2660 (insert "\n")))
2661 (when required-by
2662 (package--print-help-section "Required by")
2663 (let ((first t))
2664 (dolist (pkg required-by)
2665 (let ((text (package-desc-full-name pkg)))
2666 (cond (first (setq first nil))
2667 ((>= (+ 2 (current-column) (length text))
2668 (window-width))
2669 (insert ",\n "))
2670 (t (insert ", ")))
2671 (help-insert-xref-button text 'help-package
2672 (package-desc-name pkg))))
2673 (insert "\n")))
2674 (when website
2675 ;; Prefer https for the website of packages on common domains.
2676 (when (string-match-p (rx bol "http://" (or "elpa." "www." "git." "")
2677 (or "nongnu.org" "gnu.org" "sr.ht"
2678 "emacswiki.org" "gitlab.com" "github.com")
2679 "/")
2680 website)
2681 ;; But only if the user has "https" in `package-archives'.
2682 (let ((gnu (cdr (assoc "gnu" package-archives))))
2683 (and gnu (string-match-p "^https" gnu)
2684 (setq website
2685 (replace-regexp-in-string "^http" "https" website)))))
2686 (package--print-help-section "Website")
2687 (help-insert-xref-button website 'help-url website)
2688 (insert "\n"))
2689 (when keywords
2690 (package--print-help-section "Keywords")
2691 (dolist (k keywords)
2692 (package-make-button
2693 k
2694 'package-keyword k
2695 'action 'package-keyword-button-action)
2696 (insert " "))
2697 (insert "\n"))
2698 (when maintainers
2699 (unless (and (listp (car maintainers)) (listp (cdr maintainers)))
2700 (setq maintainers (list maintainers)))
2701 (package--print-help-section
2702 (if (cdr maintainers) "Maintainers" "Maintainer"))
2703 (dolist (maintainer maintainers)
2704 (when (bolp)
2705 (insert (make-string 13 ?\s)))
2706 (package--print-email-button maintainer)))
2707 (when authors
2708 (package--print-help-section (if (cdr authors) "Authors" "Author"))
2709 (dolist (author authors)
2710 (when (bolp)
2711 (insert (make-string 13 ?\s)))
2712 (package--print-email-button author)))
2713 (let* ((all-pkgs (append (cdr (assq name package-alist))
2714 (cdr (assq name package-archive-contents))
2715 (let ((bi (assq name package--builtins)))
2716 (if bi (list (package--from-builtin bi))))))
2717 (other-pkgs (delete desc all-pkgs)))
2718 (when other-pkgs
2719 (package--print-help-section "Other versions"
2720 (mapconcat (lambda (opkg)
2721 (let* ((ov (package-desc-version opkg))
2722 (dir (package-desc-dir opkg))
2723 (from (or (package-desc-archive opkg)
2724 (if (stringp dir) "installed" dir))))
2725 (if (not ov) (format "%s" from)
2726 (format "%s (%s)"
2727 (make-text-button (package-version-join ov) nil
2728 'font-lock-face 'link
2729 'follow-link t
2730 'action
2731 (lambda (_button)
2732 (describe-package opkg)))
2733 from))))
2734 other-pkgs ", ")
2735 ".")))
2736
2737 (insert "\n")
2738
2739 (let ((start-of-description (point)))
2740 (if built-in
2741 ;; For built-in packages, get the description from the
2742 ;; Commentary header.
2743 (insert (or (lm-commentary (locate-file (format "%s.el" name)
2744 load-path
2745 load-file-rep-suffixes))
2746 ""))
2747
2748 (if (package-installed-p desc)
2749 ;; For installed packages, get the description from the
2750 ;; installed files.
2751 (insert (package--get-description desc))
2752
2753 ;; For non-built-in, non-installed packages, get description from
2754 ;; the archive.
2755 (let* ((basename (format "%s-readme.txt" name))
2756 readme-string)
2757
2758 (package--with-response-buffer (package-archive-base desc)
2759 :file basename :noerror t
2760 (save-excursion
2761 (goto-char (point-max))
2762 (unless (bolp)
2763 (insert ?\n)))
2764 (cl-assert (not enable-multibyte-characters))
2765 (setq readme-string
2766 ;; The readme.txt files are defined to contain utf-8 text.
2767 (decode-coding-region (point-min) (point-max) 'utf-8 t))
2768 t)
2769 (insert (or readme-string
2770 "This package does not provide a description.")))))
2771
2772 ;; Insert news if available.
2773 (when news
2774 (insert "\n" (make-separator-line) "\n"
2775 (propertize "* News" 'face 'package-help-section-name)
2776 "\n\n")
2777 (insert-file-contents news))
2778
2779 ;; Make library descriptions into links.
2780 (goto-char start-of-description)
2781 (package--describe-add-library-links)
2782 ;; Make URLs in the description into links.
2783 (goto-char start-of-description)
2784 (browse-url-add-buttons))))
2785
2786(defun package-install-button-action (button)
2787 "Run `package-install' on the package BUTTON points to.
2788Used for the `action' property of buttons in the buffer created by
2789`describe-package'."
2790 (let ((pkg-desc (button-get button 'package-desc)))
2791 (when (y-or-n-p (format-message "Install package `%s'? "
2792 (package-desc-full-name pkg-desc)))
2793 (package-install pkg-desc nil)
2794 (describe-package (package-desc-name pkg-desc)))))
2795
2796(defun package-delete-button-action (button)
2797 "Run `package-delete' on the package BUTTON points to.
2798Used for the `action' property of buttons in the buffer created by
2799`describe-package'."
2800 (let ((pkg-desc (button-get button 'package-desc)))
2801 (when (y-or-n-p (format-message "Delete package `%s'? "
2802 (package-desc-full-name pkg-desc)))
2803 (package-delete pkg-desc)
2804 (describe-package (package-desc-name pkg-desc)))))
2805
2806(defun package-keyword-button-action (button)
2807 "Show filtered \"*Packages*\" buffer for BUTTON.
2808The buffer is filtered by the `package-keyword' property of BUTTON.
2809Used for the `action' property of buttons in the buffer created by
2810`describe-package'."
2811 (let ((pkg-keyword (button-get button 'package-keyword)))
2812 (package-show-package-list t (list pkg-keyword))))
2813
2814(defun package-make-button (text &rest properties)
2815 "Insert button labeled TEXT with button PROPERTIES at point.
2816PROPERTIES are passed to `insert-text-button', for which this
2817function is a convenience wrapper used by `describe-package-1'."
2818 (let ((button-text (if (display-graphic-p) text (concat "[" text "]")))
2819 (button-face (if (display-graphic-p)
2820 (progn
2821 (require 'cus-edit) ; for the custom-button face
2822 'custom-button)
2823 'link)))
2824 (apply #'insert-text-button button-text 'face button-face 'follow-link t
2825 properties)))
2826
2827(defun package--finder-goto-xref (button)
2828 "Jump to a Lisp file for the BUTTON at point."
2829 (let* ((file (button-get button 'xref))
2830 (lib (locate-library file)))
2831 (if lib (finder-commentary lib)
2832 (message "Unable to locate `%s'" file))))
2833
2834(define-button-type 'package--finder-xref 'action #'package--finder-goto-xref)
2835
2836(defun package--print-email-button (recipient)
2837 "Insert a button whose action will send an email to RECIPIENT.
2838NAME should have the form (FULLNAME . EMAIL) where FULLNAME is
2839either a full name or nil, and EMAIL is a valid email address."
2840 (when (car recipient)
2841 (insert (car recipient)))
2842 (when (and (car recipient) (cdr recipient))
2843 (insert " "))
2844 (when (cdr recipient)
2845 (insert "<")
2846 (insert-text-button (cdr recipient)
2847 'follow-link t
2848 'action (lambda (_)
2849 (compose-mail
2850 (format "%s <%s>" (car recipient) (cdr recipient)))))
2851 (insert ">"))
2852 (insert "\n"))
2853
2854
2855;;;; Package menu mode.
2856
2857(defvar-keymap package-menu-mode-map
2858 :doc "Local keymap for `package-menu-mode' buffers."
2859 :parent tabulated-list-mode-map
2860 "C-m" #'package-menu-describe-package
2861 "u" #'package-menu-mark-unmark
2862 "DEL" #'package-menu-backup-unmark
2863 "d" #'package-menu-mark-delete
2864 "i" #'package-menu-mark-install
2865 "U" #'package-menu-mark-upgrades
2866 "r" #'revert-buffer
2867 "~" #'package-menu-mark-obsolete-for-deletion
2868 "w" #'package-browse-url
2869 "b" #'package-report-bug
2870 "x" #'package-menu-execute
2871 "h" #'package-menu-quick-help
2872 "H" #'package-menu-hide-package
2873 "?" #'package-menu-describe-package
2874 "(" #'package-menu-toggle-hiding
2875 "/ /" #'package-menu-clear-filter
2876 "/ a" #'package-menu-filter-by-archive
2877 "/ d" #'package-menu-filter-by-description
2878 "/ k" #'package-menu-filter-by-keyword
2879 "/ N" #'package-menu-filter-by-name-or-description
2880 "/ n" #'package-menu-filter-by-name
2881 "/ s" #'package-menu-filter-by-status
2882 "/ v" #'package-menu-filter-by-version
2883 "/ m" #'package-menu-filter-marked
2884 "/ u" #'package-menu-filter-upgradable)
2885
2886(easy-menu-define package-menu-mode-menu package-menu-mode-map
2887 "Menu for `package-menu-mode'."
2888 '("Package"
2889 ["Describe Package" package-menu-describe-package :help "Display information about this package"]
2890 ["Open Package Website" package-browse-url
2891 :help "Open the website of this package"]
2892 ["Help" package-menu-quick-help :help "Show short key binding help for package-menu-mode"]
2893 "--"
2894 ["Refresh Package List" revert-buffer
2895 :help "Redownload the package archive(s)"
2896 :active (not package--downloads-in-progress)]
2897 ["Execute Marked Actions" package-menu-execute :help "Perform all the marked actions"]
2898
2899 "--"
2900 ["Mark All Available Upgrades" package-menu-mark-upgrades
2901 :help "Mark packages that have a newer version for upgrading"
2902 :active (not package--downloads-in-progress)]
2903 ["Mark All Obsolete for Deletion" package-menu-mark-obsolete-for-deletion :help "Mark all obsolete packages for deletion"]
2904 ["Mark for Install" package-menu-mark-install :help "Mark a package for installation and move to the next line"]
2905 ["Mark for Deletion" package-menu-mark-delete :help "Mark a package for deletion and move to the next line"]
2906 ["Unmark" package-menu-mark-unmark :help "Clear any marks on a package and move to the next line"]
2907
2908 "--"
2909 ("Filter Packages"
2910 ["Filter by Archive" package-menu-filter-by-archive
2911 :help
2912 "Prompt for archive(s), display only packages from those archives"]
2913 ["Filter by Description" package-menu-filter-by-description
2914 :help
2915 "Prompt for regexp, display only packages with matching description"]
2916 ["Filter by Keyword" package-menu-filter-by-keyword
2917 :help
2918 "Prompt for keyword(s), display only packages with matching keywords"]
2919 ["Filter by Name" package-menu-filter-by-name
2920 :help
2921 "Prompt for regexp, display only packages whose names match the regexp"]
2922 ["Filter by Name or Description" package-menu-filter-by-name-or-description
2923 :help
2924 "Prompt for regexp, display only packages whose name or description matches"]
2925 ["Filter by Status" package-menu-filter-by-status
2926 :help
2927 "Prompt for status(es), display only packages with those statuses"]
2928 ["Filter by Upgrades available" package-menu-filter-upgradable
2929 :help "Display only installed packages for which upgrades are available"]
2930 ["Filter by Version" package-menu-filter-by-version
2931 :help
2932 "Prompt for version and comparison operator, display only packages of matching versions"]
2933 ["Filter Marked" package-menu-filter-marked
2934 :help "Display only packages marked for installation or deletion"]
2935 ["Clear Filter" package-menu-clear-filter
2936 :help "Clear package list filtering, display the entire list again"])
2937
2938 ["Hide by Regexp" package-menu-hide-package
2939 :help "Toggle visibility of obsolete and unwanted packages"]
2940 ["Display Older Versions" package-menu-toggle-hiding
2941 :style toggle :selected (not package-menu--hide-packages)
2942 :help "Display package even if a newer version is already installed"]
2943
2944 "--"
2945 ["Quit" quit-window :help "Quit package selection"]
2946 ["Customize" (customize-group 'package)]))
2947
2948(defvar package-menu--new-package-list nil
2949 "List of newly-available packages since `list-packages' was last called.")
2950
2951(defvar package-menu--transaction-status nil
2952 "Mode-line status of ongoing package transaction.")
2953
2954(defconst package-menu-mode-line-format
2955 '((package-menu-mode-line-info
2956 (:eval (symbol-value 'package-menu-mode-line-info)))))
2957
2958(defvar-local package-menu-mode-line-info nil
2959 "Variable which stores package-menu mode-line format.")
2960
2961(defun package-menu--set-mode-line-format ()
2962 "Display package-menu mode-line."
2963 (when-let* ((buf (get-buffer "*Packages*"))
2964 ((buffer-live-p buf)))
2965 (with-current-buffer buf
2966 (setq package-menu-mode-line-info
2967 (let ((installed 0)
2968 (new 0)
2969 (total (length package-archive-contents))
2970 (to-upgrade (length (package-menu--find-upgrades)))
2971 (total-help "Total number of packages of all package archives")
2972 (installed-help "Total number of packages installed")
2973 (upgrade-help "Total number of packages to upgrade")
2974 (new-help "Total number of packages added recently"))
2975
2976 (save-excursion
2977 (goto-char (point-min))
2978 (while (not (eobp))
2979 (let ((status (package-menu-get-status)))
2980 (cond
2981 ((member status
2982 '("installed" "dependency" "unsigned"))
2983 (setq installed (1+ installed)))
2984 ((equal status "new")
2985 (setq new (1+ new)))))
2986 (forward-line)))
2987
2988 (setq installed (number-to-string installed))
2989 (setq total (number-to-string total))
2990 (setq to-upgrade (number-to-string to-upgrade))
2991
2992 (list
2993 " ["
2994 (propertize "Total: " 'help-echo total-help)
2995 (propertize total
2996 'help-echo total-help
2997 'face 'package-mode-line-total)
2998 " / "
2999 (propertize "Installed: " 'help-echo installed-help)
3000 (propertize installed
3001 'help-echo installed-help
3002 'face 'package-mode-line-installed)
3003 " / "
3004 (propertize "To Upgrade: " 'help-echo upgrade-help)
3005 (propertize to-upgrade
3006 'help-echo upgrade-help
3007 'face 'package-mode-line-to-upgrade)
3008 (when (> new 0)
3009 (concat
3010 " / "
3011 (propertize "New: " 'help-echo new-help)
3012 (propertize (number-to-string new)
3013 'help-echo new-help
3014 'face 'package-mode-line-new)))
3015 "] "))))))
3016(defvar package-menu--tool-bar-map
3017 (let ((map (make-sparse-keymap)))
3018 (tool-bar-local-item-from-menu
3019 #'package-menu-execute "package-menu/execute"
3020 map package-menu-mode-map)
3021 (define-key-after map [separator-1] menu-bar-separator)
3022 (tool-bar-local-item-from-menu
3023 #'package-menu-mark-unmark "package-menu/unmark"
3024 map package-menu-mode-map)
3025 (tool-bar-local-item-from-menu
3026 #'package-menu-mark-install "package-menu/install"
3027 map package-menu-mode-map)
3028 (tool-bar-local-item-from-menu
3029 #'package-menu-mark-delete "package-menu/delete"
3030 map package-menu-mode-map)
3031 (tool-bar-local-item-from-menu
3032 #'package-menu-describe-package "package-menu/info"
3033 map package-menu-mode-map)
3034 (tool-bar-local-item-from-menu
3035 #'package-browse-url "package-menu/url"
3036 map package-menu-mode-map)
3037 (tool-bar-local-item
3038 "package-menu/upgrade" 'package-upgrade-all
3039 'package-upgrade-all
3040 map :help "Upgrade all the packages")
3041 (define-key-after map [separator-2] menu-bar-separator)
3042 (tool-bar-local-item
3043 "search" 'isearch-forward 'search map
3044 :help "Search" :vert-only t)
3045 (tool-bar-local-item-from-menu
3046 #'revert-buffer "refresh"
3047 map package-menu-mode-map)
3048 (tool-bar-local-item-from-menu
3049 #'quit-window "close"
3050 map package-menu-mode-map)
3051 map))
3052
3053(define-derived-mode package-menu-mode tabulated-list-mode "Package Menu"
3054 "Major mode for browsing a list of packages.
3055The most useful commands here are:
3056
3057 `x': Install the package under point if it isn't already installed,
3058 and delete it if it's already installed,
3059 `i': mark a package for installation, and
3060 `d': mark a package for deletion. Use the `x' command to perform the
3061 actions on the marked files.
3062\\<package-menu-mode-map>
3063\\{package-menu-mode-map}"
3064 :interactive nil
3065 (setq mode-line-process '((package--downloads-in-progress ":Loading")
3066 (package-menu--transaction-status
3067 package-menu--transaction-status)))
3068 (setq-local mode-line-misc-info
3069 (append
3070 mode-line-misc-info
3071 package-menu-mode-line-format))
3072 (setq-local tool-bar-map package-menu--tool-bar-map)
3073 (setq tabulated-list-format
3074 `[("Package" ,package-name-column-width package-menu--name-predicate)
3075 ("Version" ,package-version-column-width package-menu--version-predicate)
3076 ("Status" ,package-status-column-width package-menu--status-predicate)
3077 ("Archive" ,package-archive-column-width package-menu--archive-predicate)
3078 ("Description" 0 package-menu--description-predicate)])
3079 (setq tabulated-list-padding 2)
3080 (setq tabulated-list-sort-key (cons "Status" nil))
3081 (add-hook 'tabulated-list-revert-hook #'package-menu--refresh nil t)
3082 (tabulated-list-init-header)
3083 (setq revert-buffer-function 'package-menu--refresh-contents)
3084 (setf imenu-prev-index-position-function
3085 #'package--imenu-prev-index-position-function)
3086 (setf imenu-extract-index-name-function
3087 #'package--imenu-extract-index-name-function))
3088
3089(defmacro package--push (pkg-desc status listname)
3090 "Convenience macro for `package-menu--generate'.
3091If the alist stored in the symbol LISTNAME lacks an entry for a
3092package PKG-DESC, add one. The alist is keyed with PKG-DESC."
3093 (declare (obsolete nil "27.1"))
3094 `(unless (assoc ,pkg-desc ,listname)
3095 ;; FIXME: Should we move status into pkg-desc?
3096 (push (cons ,pkg-desc ,status) ,listname)))
3097
3098(defvar package-list-unversioned nil
3099 "If non-nil, include packages that don't have a version in `list-packages'.")
3100
3101(defvar package-list-unsigned nil
3102 "If non-nil, mention in the list which packages were installed without signature.")
3103
3104(defvar package--emacs-version-list (version-to-list emacs-version)
3105 "The value of variable `emacs-version' as a list.")
3106
3107(defun package--ensure-package-menu-mode ()
3108 "Signal a user-error if major mode is not `package-menu-mode'."
3109 (unless (derived-mode-p 'package-menu-mode)
3110 (user-error "The current buffer is not a Package Menu")))
3111
3112(defun package--incompatible-p (pkg &optional shallow)
3113 "Return non-nil if PKG has no chance of being installable.
3114PKG is a `package-desc' object.
3115
3116If SHALLOW is non-nil, this only checks if PKG depends on a
3117higher `emacs-version' than the one being used. Otherwise, also
3118checks the viability of dependencies, according to
3119`package--compatibility-table'.
3120
3121If PKG requires an incompatible Emacs version, the return value
3122is this version (as a string).
3123If PKG requires incompatible packages, the return value is a list
3124of these dependencies, similar to the list returned by
3125`package-desc-reqs'."
3126 (let* ((reqs (package-desc-reqs pkg))
3127 (version (cadr (assq 'emacs reqs))))
3128 (if (and version (version-list-< package--emacs-version-list version))
3129 (package-version-join version)
3130 (unless shallow
3131 (let (out)
3132 (dolist (dep (package-desc-reqs pkg) out)
3133 (let ((dep-name (car dep)))
3134 (unless (eq 'emacs dep-name)
3135 (let ((cv (gethash dep-name package--compatibility-table)))
3136 (when (version-list-< (or cv '(0)) (or (cadr dep) '(0)))
3137 (push dep out)))))))))))
3138
3139(defun package-desc-status (pkg-desc)
3140 "Return the status of `package-desc' object PKG-DESC."
3141 (let* ((name (package-desc-name pkg-desc))
3142 (dir (package-desc-dir pkg-desc))
3143 (lle (assq name package-load-list))
3144 (held (cadr lle))
3145 (version (package-desc-version pkg-desc))
3146 (signed (or (not package-list-unsigned)
3147 (package-desc-signed pkg-desc))))
3148 (cond
3149 ((package-vc-p pkg-desc) "source")
3150 ((eq dir 'builtin) "built-in")
3151 ((and lle (null held)) "disabled")
3152 ((stringp held)
3153 (let ((hv (if (stringp held) (version-to-list held))))
3154 (cond
3155 ((version-list-= version hv) "held")
3156 ((version-list-< version hv) "obsolete")
3157 (t "disabled"))))
3158 (dir ;One of the installed packages.
3159 (cond
3160 ((not (file-exists-p dir)) "deleted")
3161 ;; Not inside `package-user-dir'.
3162 ((not (file-in-directory-p dir package-user-dir)) "external")
3163 ((eq pkg-desc (cadr (assq name package-alist)))
3164 (if (not signed) "unsigned"
3165 (if (package--user-selected-p name)
3166 "installed" "dependency")))
3167 (t "obsolete")))
3168 ((package--incompatible-p pkg-desc) "incompat")
3169 (t
3170 (let* ((ins (cadr (assq name package-alist)))
3171 (ins-v (if ins (package-desc-version ins))))
3172 (cond
3173 ;; Installed obsolete packages are handled in the `dir'
3174 ;; clause above. Here we handle available obsolete, which
3175 ;; are displayed depending on `package-menu--hide-packages'.
3176 ((and ins (version-list-<= version ins-v)) "avail-obso")
3177 (t
3178 (if (memq name package-menu--new-package-list)
3179 "new" "available"))))))))
3180
3181(defvar package-menu--hide-packages t
3182 "Whether available obsolete packages should be hidden.
3183Can be toggled with \\<package-menu-mode-map> \\[package-menu-toggle-hiding].
3184Installed obsolete packages are always displayed.")
3185
3186(defun package-menu-toggle-hiding ()
3187 "In Package Menu, toggle visibility of obsolete available packages.
3188
3189Also hide packages whose name matches a regexp in user option
3190`package-hidden-regexps' (a list). To add regexps to this list,
3191use `package-menu-hide-package'."
3192 (interactive nil package-menu-mode)
3193 (package--ensure-package-menu-mode)
3194 (setq package-menu--hide-packages
3195 (not package-menu--hide-packages))
3196 (if package-menu--hide-packages
3197 (message "Hiding obsolete or unwanted packages")
3198 (message "Displaying all packages"))
3199 (revert-buffer nil 'no-confirm))
3200
3201(defun package--remove-hidden (pkg-list)
3202 "Filter PKG-LIST according to `package-archive-priorities'.
3203PKG-LIST must be a list of `package-desc' objects, all with the
3204same name, sorted by decreasing `package-desc-priority-version'.
3205Return a list of packages tied for the highest priority according
3206to their archives."
3207 (when pkg-list
3208 ;; Variable toggled with `package-menu-toggle-hiding'.
3209 (if (not package-menu--hide-packages)
3210 pkg-list
3211 (let ((installed (cadr (assq (package-desc-name (car pkg-list))
3212 package-alist))))
3213 (when installed
3214 (setq pkg-list
3215 (let ((ins-version (package-desc-version installed)))
3216 (cl-remove-if (lambda (p) (version-list-< (package-desc-version p)
3217 ins-version))
3218 pkg-list))))
3219 (let ((filtered-by-priority
3220 (cond
3221 ((not package-menu-hide-low-priority)
3222 pkg-list)
3223 ((eq package-menu-hide-low-priority 'archive)
3224 (let (max-priority out)
3225 (while pkg-list
3226 (let ((p (pop pkg-list)))
3227 (let ((priority (package-desc-priority p)))
3228 (if (and max-priority (< priority max-priority))
3229 (setq pkg-list nil)
3230 (push p out)
3231 (setq max-priority priority)))))
3232 (nreverse out)))
3233 (pkg-list
3234 (list (car pkg-list))))))
3235 (if (not installed)
3236 filtered-by-priority
3237 (let ((ins-version (package-desc-version installed)))
3238 (cl-remove-if (lambda (p) (or (version-list-= (package-desc-version p)
3239 ins-version)
3240 (package-vc-p installed)))
3241 filtered-by-priority))))))))
3242
3243(defcustom package-hidden-regexps nil
3244 "List of regexps matching the name of packages to hide.
3245If the name of a package matches any of these regexps it is
3246omitted from the package menu. To toggle this, type \\[package-menu-toggle-hiding].
3247
3248Values can be interactively added to this list by typing
3249\\[package-menu-hide-package] on a package."
3250 :version "25.1"
3251 :type '(repeat (regexp :tag "Hide packages with name matching")))
3252
3253(defcustom package-menu-use-current-if-no-marks t
3254 "Whether \\<package-menu-mode-map>\\[package-menu-execute] in package menu operates on current package if none are marked.
3255
3256If non-nil, and no packages are marked for installation or
3257deletion, \\<package-menu-mode-map>\\[package-menu-execute] will operate on the current package at point,
3258see `package-menu-execute' for details.
3259The default is t. Set to nil to get back the original behavior
3260of having `package-menu-execute' signal an error when no packages
3261are marked for installation or deletion."
3262 :version "29.1"
3263 :type 'boolean)
3264
3265(defun package-menu--refresh (&optional packages keywords)
3266 "Re-populate the `tabulated-list-entries'.
3267PACKAGES should be nil or t, which means to display all known packages.
3268KEYWORDS should be nil or a list of keywords."
3269 ;; Construct list of (PKG-DESC . STATUS).
3270 (unless packages (setq packages t))
3271 (let ((hidden-names (mapconcat #'identity package-hidden-regexps "\\|"))
3272 info-list)
3273 ;; Installed packages:
3274 (dolist (elt package-alist)
3275 (let ((name (car elt)))
3276 (when (or (eq packages t) (memq name packages))
3277 (dolist (pkg (cdr elt))
3278 (when (package--has-keyword-p pkg keywords)
3279 (push pkg info-list))))))
3280
3281 ;; Built-in packages:
3282 (dolist (elt package--builtins)
3283 (let ((pkg (package--from-builtin elt))
3284 (name (car elt)))
3285 (when (not (eq name 'emacs)) ; Hide the `emacs' package.
3286 (when (and (package--has-keyword-p pkg keywords)
3287 (or package-list-unversioned
3288 (package--bi-desc-version (cdr elt)))
3289 (or (eq packages t) (memq name packages)))
3290 (push pkg info-list)))))
3291
3292 ;; Available and disabled packages:
3293 (unless (equal package--old-archive-priorities package-archive-priorities)
3294 (package-read-all-archive-contents))
3295 (dolist (elt package-archive-contents)
3296 (let ((name (car elt)))
3297 ;; To be displayed it must be in PACKAGES;
3298 (when (and (or (eq packages t) (memq name packages))
3299 ;; and we must either not be hiding anything,
3300 (or (not package-menu--hide-packages)
3301 (not package-hidden-regexps)
3302 ;; or just not hiding this specific package.
3303 (not (string-match hidden-names (symbol-name name)))))
3304 ;; Hide available-obsolete or low-priority packages.
3305 (dolist (pkg (package--remove-hidden (cdr elt)))
3306 (when (package--has-keyword-p pkg keywords)
3307 (push pkg info-list))))))
3308
3309 ;; Print the result.
3310 (tabulated-list-init-header)
3311 (setq tabulated-list-entries
3312 (mapcar #'package-menu--print-info-simple info-list))))
3313
3314(defun package-all-keywords ()
3315 "Collect all package keywords."
3316 (let ((key-list))
3317 (package--mapc (lambda (desc)
3318 (setq key-list (append (package-desc--keywords desc)
3319 key-list))))
3320 key-list))
3321
3322(defun package--mapc (function &optional packages)
3323 "Call FUNCTION for all known PACKAGES.
3324PACKAGES can be nil or t, which means to display all known
3325packages, or a list of packages.
3326
3327Built-in packages are converted with `package--from-builtin'."
3328 (unless packages (setq packages t))
3329 (let (name)
3330 ;; Installed packages:
3331 (dolist (elt package-alist)
3332 (setq name (car elt))
3333 (when (or (eq packages t) (memq name packages))
3334 (mapc function (cdr elt))))
3335
3336 ;; Built-in packages:
3337 (dolist (elt package--builtins)
3338 (setq name (car elt))
3339 (when (and (not (eq name 'emacs)) ; Hide the `emacs' package.
3340 (or package-list-unversioned
3341 (package--bi-desc-version (cdr elt)))
3342 (or (eq packages t) (memq name packages)))
3343 (funcall function (package--from-builtin elt))))
3344
3345 ;; Available and disabled packages:
3346 (dolist (elt package-archive-contents)
3347 (setq name (car elt))
3348 (when (or (eq packages t) (memq name packages))
3349 (dolist (pkg (cdr elt))
3350 ;; Hide obsolete packages.
3351 (unless (package-installed-p (package-desc-name pkg)
3352 (package-desc-version pkg))
3353 (funcall function pkg)))))))
3354
3355(defun package--has-keyword-p (desc &optional keywords)
3356 "Test if package DESC has any of the given KEYWORDS.
3357When none are given, the package matches."
3358 (if keywords
3359 (let ((desc-keywords (and desc (package-desc--keywords desc)))
3360 found)
3361 (while (and (not found) keywords)
3362 (let ((k (pop keywords)))
3363 (setq found
3364 (or (string= k (concat "arc:" (package-desc-archive desc)))
3365 (string= k (concat "status:" (package-desc-status desc)))
3366 (member k desc-keywords)))))
3367 found)
3368 t))
3369
3370(defun package-menu--display (remember-pos suffix)
3371 "Display the Package Menu.
3372If REMEMBER-POS is non-nil, keep point on the same entry.
3373
3374If SUFFIX is non-nil, append that to \"Package\" for the first
3375column in the header line."
3376 (setf (car (aref tabulated-list-format 0))
3377 (if suffix
3378 (concat "Package[" suffix "]")
3379 "Package"))
3380 (tabulated-list-init-header)
3381 (tabulated-list-print remember-pos))
3382
3383(defun package-menu--generate (remember-pos &optional packages keywords)
3384 "Populate and display the Package Menu.
3385If REMEMBER-POS is non-nil, keep point on the same entry.
3386PACKAGES should be t, which means to display all known packages,
3387or a list of package names (symbols) to display.
3388
3389With KEYWORDS given, only packages with those keywords are
3390shown."
3391 (package-menu--refresh packages keywords)
3392 (package-menu--display remember-pos
3393 (when keywords
3394 (let ((filters (mapconcat #'identity keywords ",")))
3395 (concat "Package[" filters "]")))))
3396
3397(defun package-menu--print-info (pkg)
3398 "Return a package entry suitable for `tabulated-list-entries'.
3399PKG has the form (PKG-DESC . STATUS).
3400Return (PKG-DESC [NAME VERSION STATUS DOC])."
3401 (package-menu--print-info-simple (car pkg)))
3402(make-obsolete 'package-menu--print-info
3403 'package-menu--print-info-simple "25.1")
3404
3405
3406;;; Package menu faces
3407
3408(defface package-name
3409 '((t :inherit link))
3410 "Face used on package names in the package menu."
3411 :version "25.1")
3412
3413(defface package-description
3414 '((t :inherit default))
3415 "Face used on package description summaries in the package menu."
3416 :version "25.1")
3417
3418;; Shame this hyphenates "built-in", when "font-lock-builtin-face" doesn't.
3419(defface package-status-built-in
3420 '((t :inherit font-lock-builtin-face))
3421 "Face used on the status and version of built-in packages."
3422 :version "25.1")
3423
3424(defface package-status-external
3425 '((t :inherit package-status-built-in))
3426 "Face used on the status and version of external packages."
3427 :version "25.1")
3428
3429(defface package-status-available
3430 '((t :inherit default))
3431 "Face used on the status and version of available packages."
3432 :version "25.1")
3433
3434(defface package-status-new
3435 '((t :inherit (bold package-status-available)))
3436 "Face used on the status and version of new packages."
3437 :version "25.1")
3438
3439(defface package-status-held
3440 '((t :inherit font-lock-constant-face))
3441 "Face used on the status and version of held packages."
3442 :version "25.1")
3443
3444(defface package-status-disabled
3445 '((t :inherit font-lock-warning-face))
3446 "Face used on the status and version of disabled packages."
3447 :version "25.1")
3448
3449(defface package-status-installed
3450 '((t :inherit font-lock-comment-face))
3451 "Face used on the status and version of installed packages."
3452 :version "25.1")
3453
3454(defface package-status-from-source
3455 '((t :inherit font-lock-negation-char-face))
3456 "Face used on the status and version of installed packages."
3457 :version "29.1")
3458
3459(defface package-status-dependency
3460 '((t :inherit package-status-installed))
3461 "Face used on the status and version of dependency packages."
3462 :version "25.1")
3463
3464(defface package-status-unsigned
3465 '((t :inherit font-lock-warning-face))
3466 "Face used on the status and version of unsigned packages."
3467 :version "25.1")
3468
3469(defface package-status-incompat
3470 '((t :inherit error))
3471 "Face used on the status and version of incompat packages."
3472 :version "25.1")
3473
3474(defface package-status-avail-obso
3475 '((t :inherit package-status-incompat))
3476 "Face used on the status and version of avail-obso packages."
3477 :version "25.1")
3478
3479(defface package-mark-install-line
3480 '((((class color) (background light))
3481 :background "darkolivegreen1" :extend t)
3482 (((class color) (background dark))
3483 :background "seagreen" :extend t)
3484 (t :inherit (highlight) :extend t))
3485 "Face used for highlighting in package-menu packages marked to be installed."
3486 :version "31.1")
3487
3488(defface package-mark-delete-line
3489 '((((class color) (background light))
3490 :background "rosybrown1" :extend t)
3491 (((class color) (background dark))
3492 :background "indianred4" :extend t)
3493 (t :inherit (highlight) :extend t))
3494 "Face used for highlighting in package-menu packages marked to be deleted."
3495 :version "31.1")
3496
3497(defface package-mode-line-total nil
3498 "Face for the total number of packages displayed on the mode line."
3499 :version "31.1")
3500
3501(defface package-mode-line-installed '((t :inherit package-status-installed))
3502 "Face for the number of installed packages displayed on the mode line."
3503 :version "31.1")
3504
3505(defface package-mode-line-to-upgrade '((t :inherit bold))
3506 "Face for the number of packages to upgrade displayed on the mode line."
3507 :version "31.1")
3508
3509(defface package-mode-line-new '((t :inherit package-status-new))
3510 "Face for the number of new packages displayed on the mode line."
3511 :version "31.1")
3512
3513
3514;;; Package menu printing
3515
3516(defun package-menu--print-info-simple (pkg)
3517 "Return a package entry suitable for `tabulated-list-entries'.
3518PKG is a `package-desc' object.
3519Return (PKG-DESC [NAME VERSION STATUS DOC])."
3520 (let* ((status (package-desc-status pkg))
3521 (face (pcase status
3522 ("built-in" 'package-status-built-in)
3523 ("external" 'package-status-external)
3524 ("available" 'package-status-available)
3525 ("avail-obso" 'package-status-avail-obso)
3526 ("new" 'package-status-new)
3527 ("held" 'package-status-held)
3528 ("disabled" 'package-status-disabled)
3529 ("installed" 'package-status-installed)
3530 ("source" 'package-status-from-source)
3531 ("dependency" 'package-status-dependency)
3532 ("unsigned" 'package-status-unsigned)
3533 ("incompat" 'package-status-incompat)
3534 (_ 'font-lock-warning-face)))) ; obsolete.
3535 (list pkg
3536 `[(,(symbol-name (package-desc-name pkg))
3537 face package-name
3538 font-lock-face package-name
3539 follow-link t
3540 package-desc ,pkg
3541 action package-menu-describe-package)
3542 ,(propertize
3543 (if (package-vc-p pkg)
3544 (progn
3545 (require 'package-vc)
3546 (package-vc-commit pkg))
3547 (package-version-join
3548 (package-desc-version pkg)))
3549 'font-lock-face face)
3550 ,(propertize status 'font-lock-face face)
3551 ,(propertize (or (package-desc-archive pkg) "")
3552 'font-lock-face face)
3553 ,(propertize (package-desc-summary pkg)
3554 'font-lock-face 'package-description)])))
3555
3556(defvar package-menu--old-archive-contents nil
3557 "`package-archive-contents' before the latest refresh.")
3558
3559(defun package-menu--refresh-contents (&optional _arg _noconfirm)
3560 "In Package Menu, download the Emacs Lisp package archive.
3561Fetch the contents of each archive specified in
3562`package-archives', and then refresh the package menu.
3563
3564`package-menu-mode' sets `revert-buffer-function' to this
3565function. The args ARG and NOCONFIRM, passed from
3566`revert-buffer', are ignored."
3567 (package--ensure-package-menu-mode)
3568 (setq package-menu--old-archive-contents package-archive-contents)
3569 (setq package-menu--new-package-list nil)
3570 (package-refresh-contents package-menu-async))
3571(define-obsolete-function-alias 'package-menu-refresh 'revert-buffer "27.1")
3572
3573(defun package-menu--overlay-line (face)
3574 "Highlight whole line with face FACE."
3575 (let ((ov (make-overlay (line-beginning-position)
3576 (1+ (line-end-position)))))
3577 (overlay-put ov 'pkg-menu-ov t)
3578 (overlay-put ov 'evaporate t)
3579 (overlay-put ov 'face face)))
3580
3581(defun package-menu--remove-overlay ()
3582 "Remove all overlays done by `package-menu--overlay-line' in current line."
3583 (remove-overlays (line-beginning-position)
3584 (1+ (line-end-position))
3585 'pkg-menu-ov t))
3586
3587(defun package-menu-hide-package ()
3588 "Hide in Package Menu packages that match a regexp.
3589Prompt for the regexp to match against package names.
3590The default regexp will hide only the package whose name is at point.
3591
3592The regexp is added to the list in the user option
3593`package-hidden-regexps' and saved for future sessions.
3594
3595To unhide a package, type
3596`\\[customize-variable] RET package-hidden-regexps', and then modify
3597the regexp such that it no longer matches the package's name.
3598
3599Type \\[package-menu-toggle-hiding] to toggle package hiding."
3600 (declare (interactive-only "change `package-hidden-regexps' instead."))
3601 (interactive nil package-menu-mode)
3602 (package--ensure-package-menu-mode)
3603 (let* ((name (when (derived-mode-p 'package-menu-mode)
3604 (concat "\\`" (regexp-quote (symbol-name (package-desc-name
3605 (tabulated-list-get-id))))
3606 "\\'")))
3607 (re (read-string "Hide packages matching regexp: " name)))
3608 ;; Test if it is valid.
3609 (string-match re "")
3610 (push re package-hidden-regexps)
3611 (customize-save-variable 'package-hidden-regexps package-hidden-regexps)
3612 (package-menu--post-refresh)
3613 (let ((hidden
3614 (cl-remove-if-not (lambda (e) (string-match re (symbol-name (car e))))
3615 package-archive-contents)))
3616 (message "Packages to hide: %d. Type `%s' to toggle or `%s' to customize"
3617 (length hidden)
3618 (substitute-command-keys "\\[package-menu-toggle-hiding]")
3619 (substitute-command-keys "\\[customize-variable] RET package-hidden-regexps")))))
3620
3621
3622(defun package-menu-describe-package (&optional button)
3623 "Describe the current package.
3624The current package is the package at point.
3625If optional arg BUTTON is non-nil, describe its associated
3626package(s); this is always nil in interactive invocations."
3627 (interactive nil package-menu-mode)
3628 (let ((pkg-desc (if button (button-get button 'package-desc)
3629 (tabulated-list-get-id))))
3630 (if pkg-desc
3631 (describe-package pkg-desc)
3632 (user-error "No package here"))))
3633
3634;; fixme numeric argument
3635(defun package-menu-mark-delete (&optional _num)
3636 "Mark the current package for deletion and move to the next line.
3637The current package is the package at point."
3638 (interactive "p" package-menu-mode)
3639 (package--ensure-package-menu-mode)
3640 (if (member (package-menu-get-status)
3641 '("installed" "source" "dependency" "obsolete" "unsigned"))
3642 (progn (package-menu--overlay-line 'package-mark-delete-line)
3643 (tabulated-list-put-tag "D" t))
3644 (forward-line)))
3645
3646(defun package-menu-mark-install (&optional _num)
3647 "Mark the current package for installation and move to the next line.
3648The current package is the package at point."
3649 (interactive "p" package-menu-mode)
3650 (package--ensure-package-menu-mode)
3651 (if (member (package-menu-get-status) '("available" "avail-obso" "new" "dependency"))
3652 (progn (package-menu--overlay-line 'package-mark-install-line)
3653 (tabulated-list-put-tag "I" t))
3654 (forward-line)))
3655
3656(defun package-menu-mark-unmark (&optional _num)
3657 "Clear any marks on the current package and move to the next line.
3658The current package is the package at point."
3659 (interactive "p" package-menu-mode)
3660 (package--ensure-package-menu-mode)
3661 (package-menu--remove-overlay)
3662 (tabulated-list-put-tag " " t))
3663
3664(defun package-menu-backup-unmark ()
3665 "Back up one line and clear any marks on that line's package."
3666 (interactive nil package-menu-mode)
3667 (package--ensure-package-menu-mode)
3668 (forward-line -1)
3669 (package-menu--remove-overlay)
3670 (tabulated-list-put-tag " "))
3671
3672(defun package-menu-mark-obsolete-for-deletion ()
3673 "Mark all obsolete packages for deletion."
3674 (interactive nil package-menu-mode)
3675 (package--ensure-package-menu-mode)
3676 (save-excursion
3677 (goto-char (point-min))
3678 (while (not (eobp))
3679 (if (equal (package-menu-get-status) "obsolete")
3680 (progn (package-menu--overlay-line 'package-mark-delete-line)
3681 (tabulated-list-put-tag "D" t))
3682 (forward-line 1)))))
3683
3684(defvar package--quick-help-keys
3685 '((("mark for installation," . 9)
3686 ("mark for deletion," . 9) "unmark," ("execute marked actions" . 1))
3687 ("next," "previous")
3688 ("Hide-package," "(-toggle-hidden")
3689 ("g-refresh-contents," "/-filter," "help")))
3690
3691(defun package--prettify-quick-help-key (desc)
3692 "Prettify DESC to be displayed as a help menu."
3693 (if (listp desc)
3694 (if (listp (cdr desc))
3695 (mapconcat #'package--prettify-quick-help-key desc " ")
3696 (let ((place (cdr desc))
3697 (out (copy-sequence (car desc))))
3698 (add-text-properties place (1+ place)
3699 '(face help-key-binding)
3700 out)
3701 out))
3702 (package--prettify-quick-help-key (cons desc 0))))
3703
3704(defun package-menu-quick-help ()
3705 "Show short help for key bindings in `package-menu-mode'.
3706You can view the full list of keys with \\[describe-mode]."
3707 (interactive nil package-menu-mode)
3708 (package--ensure-package-menu-mode)
3709 (message (mapconcat #'package--prettify-quick-help-key
3710 package--quick-help-keys "\n")))
3711
3712(defun package-menu-get-status ()
3713 "Return status description of package at point in Package Menu."
3714 (package--ensure-package-menu-mode)
3715 (let* ((id (tabulated-list-get-id))
3716 (entry (and id (assoc id tabulated-list-entries))))
3717 (if entry
3718 (aref (cadr entry) 2)
3719 "")))
3720
3721(defun package-archive-priority (archive)
3722 "Return the priority of ARCHIVE.
3723
3724The archive priorities are specified in
3725`package-archive-priorities'. If not given there, the priority
3726defaults to 0."
3727 (or (cdr (assoc archive package-archive-priorities))
3728 0))
3729
3730(defun package-desc-priority-version (pkg-desc)
3731 "Return the version PKG-DESC with the archive priority prepended.
3732
3733This allows for easy comparison of package versions from
3734different archives if archive priorities are meant to be taken in
3735consideration."
3736 (cons (package-desc-priority pkg-desc)
3737 (package-desc-version pkg-desc)))
3738
3739(defun package-menu--find-upgrades ()
3740 "In Package Menu, return an alist of packages that can be upgraded.
3741The alist has the same form as `package-alist', namely a list
3742of elements of the form (PKG . DESCS), but where DESCS is the `package-desc'
3743object corresponding to the newer version."
3744 (let (installed available upgrades)
3745 ;; Build list of installed/available packages in this buffer.
3746 (dolist (entry tabulated-list-entries)
3747 ;; ENTRY is (PKG-DESC [NAME VERSION STATUS DOC])
3748 (let ((pkg-desc (car entry))
3749 (status (aref (cadr entry) 2)))
3750 (cond ((member status '("installed" "dependency" "unsigned" "external" "built-in"))
3751 (push pkg-desc installed))
3752 ((member status '("available" "new"))
3753 (setq available (package--append-to-alist pkg-desc available))))))
3754 ;; Loop through list of installed packages, finding upgrades.
3755 (dolist (pkg-desc installed)
3756 (let* ((name (package-desc-name pkg-desc))
3757 (avail-pkg (cadr (assq name available))))
3758 (and avail-pkg
3759 (version-list-< (package-desc-priority-version pkg-desc)
3760 (package-desc-priority-version avail-pkg))
3761 (or (not (package--active-built-in-p pkg-desc))
3762 package-install-upgrade-built-in)
3763 (push (cons name avail-pkg) upgrades))))
3764 upgrades))
3765
3766(defvar package-menu--mark-upgrades-pending nil
3767 "Whether mark-upgrades is waiting for a refresh to finish.")
3768
3769(defun package-menu--mark-upgrades-1 ()
3770 "Mark all upgradable packages in the Package Menu.
3771Implementation of `package-menu-mark-upgrades'."
3772 (setq package-menu--mark-upgrades-pending nil)
3773 (let ((upgrades (package-menu--find-upgrades)))
3774 (if (null upgrades)
3775 (message "No packages to upgrade")
3776 (widen)
3777 (save-excursion
3778 (goto-char (point-min))
3779 (while (not (eobp))
3780 (let* ((pkg-desc (tabulated-list-get-id))
3781 (upgrade (cdr (assq (package-desc-name pkg-desc) upgrades))))
3782 (cond ((null upgrade)
3783 (forward-line 1))
3784 ((equal pkg-desc upgrade)
3785 (package-menu-mark-install))
3786 (t
3787 (package-menu-mark-delete))))))
3788 (message "Packages marked for upgrading: %d"
3789 (length upgrades)))))
3790
3791
3792(defun package-menu-mark-upgrades ()
3793 "Mark all upgradable packages in the Package Menu.
3794For each installed package for which a newer version is available,
3795place an (I)nstall flag on the available version and a (D)elete flag
3796on the installed version. A subsequent \\[package-menu-execute] command will upgrade
3797the marked packages.
3798
3799If there's an async refresh operation in progress, the flags will
3800be placed as part of `package-menu--post-refresh' instead of
3801immediately."
3802 (interactive nil package-menu-mode)
3803 (package--ensure-package-menu-mode)
3804 (if (not package--downloads-in-progress)
3805 (package-menu--mark-upgrades-1)
3806 (setq package-menu--mark-upgrades-pending t)
3807 (message "Waiting for refresh to finish...")))
3808
3809(defun package-menu--list-to-prompt (packages &optional include-dependencies)
3810 "Return a string listing PACKAGES that's usable in a prompt.
3811PACKAGES is a list of `package-desc' objects.
3812Formats the returned string to be usable in a minibuffer
3813prompt (see `package-menu--prompt-transaction-p').
3814
3815If INCLUDE-DEPENDENCIES, also include the number of uninstalled
3816dependencies."
3817 ;; The case where `package' is empty is handled in
3818 ;; `package-menu--prompt-transaction-p' below.
3819 (format "%d (%s)%s"
3820 (length packages)
3821 (mapconcat #'package-desc-full-name packages " ")
3822 (let ((deps
3823 (seq-remove
3824 #'package-installed-p
3825 (delete-dups
3826 (apply
3827 #'nconc
3828 (mapcar (lambda (package)
3829 (package--dependencies
3830 (package-desc-name package)))
3831 packages))))))
3832 (if (and include-dependencies deps)
3833 (if (length= deps 1)
3834 (format " plus 1 dependency")
3835 (format " plus %d dependencies" (length deps)))
3836 ""))))
3837
3838(defun package-menu--prompt-transaction-p (delete install upgrade)
3839 "Prompt the user about DELETE, INSTALL, and UPGRADE.
3840DELETE, INSTALL, and UPGRADE are lists of `package-desc' objects.
3841Either may be nil, but not all."
3842 (y-or-n-p
3843 (concat
3844 (when delete
3845 (format "Packages to delete: %s. "
3846 (package-menu--list-to-prompt delete)))
3847 (when install
3848 (format "Packages to install: %s. "
3849 (package-menu--list-to-prompt install t)))
3850 (when upgrade
3851 (format "Packages to upgrade: %s. "
3852 (package-menu--list-to-prompt upgrade)))
3853 "Proceed? ")))
3854
3855
3856(defun package-menu--partition-transaction (install delete)
3857 "Return an alist describing an INSTALL DELETE transaction.
3858Alist contains three entries, upgrade, delete, and install, each
3859with a list of package names.
3860
3861The upgrade entry contains any `package-desc' objects in INSTALL
3862whose name coincides with an object in DELETE. The delete and
3863the install entries are the same as DELETE and INSTALL with such
3864objects removed."
3865 (let* ((upg (cl-intersection install delete :key #'package-desc-name))
3866 (ins (cl-set-difference install upg :key #'package-desc-name))
3867 (del (cl-set-difference delete upg :key #'package-desc-name)))
3868 `((delete . ,del) (install . ,ins) (upgrade . ,upg))))
3869
3870(defun package-menu--perform-transaction (install-list delete-list)
3871 "Install packages in INSTALL-LIST and delete DELETE-LIST.
3872Return nil if there were no errors; non-nil otherwise."
3873 (let ((errors nil))
3874 (if install-list
3875 (let ((status-format (format ":Installing %%d/%d"
3876 (length install-list)))
3877 (i 0)
3878 (package-menu--transaction-status))
3879 (dolist (pkg install-list)
3880 (setq package-menu--transaction-status
3881 (format status-format (incf i)))
3882 (force-mode-line-update)
3883 (redisplay 'force)
3884 ;; Don't mark as selected, `package-menu-execute' already
3885 ;; does that.
3886 (package-install pkg 'dont-select))))
3887 (let ((package-menu--transaction-status ":Deleting"))
3888 (force-mode-line-update)
3889 (redisplay 'force)
3890 (dolist (elt (package--sort-by-dependence delete-list))
3891 (condition-case-unless-debug err
3892 (let ((inhibit-message (or inhibit-message package-menu-async)))
3893 (package-delete elt nil 'nosave))
3894 (error
3895 (push (package-desc-full-name elt) errors)
3896 (message "Error trying to delete `%s': %s"
3897 (package-desc-full-name elt)
3898 (error-message-string err))))))
3899 errors))
3900
3901(defun package--update-selected-packages (add remove)
3902 "Update the `package-selected-packages' list according to ADD and REMOVE.
3903ADD and REMOVE must be disjoint lists of package names (or
3904`package-desc' objects) to be added and removed to the selected
3905packages list, respectively."
3906 (dolist (p add)
3907 (cl-pushnew (if (package-desc-p p) (package-desc-name p) p)
3908 package-selected-packages))
3909 (dolist (p remove)
3910 (setq package-selected-packages
3911 (remove (if (package-desc-p p) (package-desc-name p) p)
3912 package-selected-packages)))
3913 (when (or add remove)
3914 (package--save-selected-packages package-selected-packages)))
3915
3916(defun package-menu-execute (&optional noquery)
3917 "Perform Package Menu actions on marked packages.
3918Packages marked for installation are downloaded and installed,
3919packages marked for deletion are removed, and packages marked for
3920upgrading are downloaded and upgraded.
3921
3922If no packages are marked, the action taken depends on the state
3923of the current package, the one at point. If it's not already
3924installed, this command will install the package; if it's installed,
3925the command will delete the package.
3926
3927Optional argument NOQUERY non-nil means do not ask the user to
3928confirm the installations/deletions; this is always nil in interactive
3929invocations."
3930 (interactive nil package-menu-mode)
3931 (package--ensure-package-menu-mode)
3932 (let (install-list delete-list cmd pkg-desc)
3933 (save-excursion
3934 (goto-char (point-min))
3935 (while (not (eobp))
3936 (setq cmd (char-after))
3937 (unless (eq cmd ?\s)
3938 ;; This is the key PKG-DESC.
3939 (setq pkg-desc (tabulated-list-get-id))
3940 (cond ((eq cmd ?D)
3941 (push pkg-desc delete-list))
3942 ((eq cmd ?I)
3943 (push pkg-desc install-list))))
3944 (forward-line)))
3945 ;; Nothing marked.
3946 (unless (or delete-list install-list)
3947 ;; Not on a package line.
3948 (unless (and (tabulated-list-get-id)
3949 package-menu-use-current-if-no-marks)
3950 (user-error "No operations specified"))
3951 (let* ((id (tabulated-list-get-id))
3952 (status (package-menu-get-status)))
3953 (cond
3954 ((member status '("installed"))
3955 (push id delete-list))
3956 ((member status '("available" "avail-obso" "new" "dependency"))
3957 (push id install-list))
3958 (t (user-error "No default action available for status: %s"
3959 status)))))
3960 (let-alist (package-menu--partition-transaction install-list delete-list)
3961 (when (or noquery
3962 (package-menu--prompt-transaction-p .delete .install .upgrade))
3963 (let ((message-template
3964 (concat "[ "
3965 (when .delete
3966 (format "Delete %d " (length .delete)))
3967 (when .install
3968 (format "Install %d " (length .install)))
3969 (when .upgrade
3970 (format "Upgrade %d " (length .upgrade)))
3971 "]")))
3972 (message "Operation %s started" message-template)
3973 ;; Packages being upgraded are not marked as selected.
3974 (package--update-selected-packages .install .delete)
3975 (unless (package-menu--perform-transaction install-list delete-list)
3976 ;; If there weren't errors, output data.
3977 (if-let* ((removable (package--removable-packages)))
3978 (message "Operation finished. Packages that are no longer needed: %d. Type `%s' to remove them"
3979 (length removable)
3980 (substitute-command-keys "\\[package-autoremove]"))
3981 (message "Operation %s finished" message-template))))))))
3982
3983(defun package-menu--version-predicate (A B)
3984 "Predicate to sort \"*Packages*\" buffer by the version column.
3985This is used for `tabulated-list-format' in `package-menu-mode'."
3986 (let ((vA (or (ignore-error error (version-to-list (aref (cadr A) 1))) '(0)))
3987 (vB (or (ignore-error error (version-to-list (aref (cadr B) 1))) '(0))))
3988 (if (version-list-= vA vB)
3989 (package-menu--name-predicate A B)
3990 (version-list-< vA vB))))
3991
3992(defun package-menu--status-predicate (A B)
3993 "Predicate to sort \"*Packages*\" buffer by the status column.
3994This is used for `tabulated-list-format' in `package-menu-mode'."
3995 (let ((sA (aref (cadr A) 2))
3996 (sB (aref (cadr B) 2)))
3997 (cond ((string= sA sB)
3998 (package-menu--name-predicate A B))
3999 ((string= sA "new") t)
4000 ((string= sB "new") nil)
4001 ((string-prefix-p "avail" sA)
4002 (if (string-prefix-p "avail" sB)
4003 (package-menu--name-predicate A B)
4004 t))
4005 ((string-prefix-p "avail" sB) nil)
4006 ((string= sA "installed") t)
4007 ((string= sB "installed") nil)
4008 ((string= sA "dependency") t)
4009 ((string= sB "dependency") nil)
4010 ((string= sA "source") t)
4011 ((string= sB "source") nil)
4012 ((string= sA "unsigned") t)
4013 ((string= sB "unsigned") nil)
4014 ((string= sA "held") t)
4015 ((string= sB "held") nil)
4016 ((string= sA "external") t)
4017 ((string= sB "external") nil)
4018 ((string= sA "built-in") t)
4019 ((string= sB "built-in") nil)
4020 ((string= sA "obsolete") t)
4021 ((string= sB "obsolete") nil)
4022 ((string= sA "incompat") t)
4023 ((string= sB "incompat") nil)
4024 (t (string< sA sB)))))
4025
4026(defun package-menu--description-predicate (A B)
4027 "Predicate to sort \"*Packages*\" buffer by the description column.
4028This is used for `tabulated-list-format' in `package-menu-mode'."
4029 (let ((dA (aref (cadr A) (if (cdr package-archives) 4 3)))
4030 (dB (aref (cadr B) (if (cdr package-archives) 4 3))))
4031 (if (string= dA dB)
4032 (package-menu--name-predicate A B)
4033 (string< dA dB))))
4034
4035(defun package-menu--name-predicate (A B)
4036 "Predicate to sort \"*Packages*\" buffer by the name column.
4037This is used for `tabulated-list-format' in `package-menu-mode'."
4038 (string< (symbol-name (package-desc-name (car A)))
4039 (symbol-name (package-desc-name (car B)))))
4040
4041(defun package-menu--archive-predicate (A B)
4042 "Predicate to sort \"*Packages*\" buffer by the archive column.
4043This is used for `tabulated-list-format' in `package-menu-mode'."
4044 (let ((a (or (package-desc-archive (car A)) ""))
4045 (b (or (package-desc-archive (car B)) "")))
4046 (if (string= a b)
4047 (package-menu--name-predicate A B)
4048 (string< a b))))
4049
4050(defun package-menu--populate-new-package-list ()
4051 "Decide which packages are new in `package-archive-contents'.
4052Store this list in `package-menu--new-package-list'."
4053 ;; Find which packages are new.
4054 (when package-menu--old-archive-contents
4055 (dolist (elt package-archive-contents)
4056 (unless (assq (car elt) package-menu--old-archive-contents)
4057 (push (car elt) package-menu--new-package-list)))
4058 (setq package-menu--old-archive-contents nil)))
4059
4060(defun package-menu--find-and-notify-upgrades ()
4061 "Notify the user of upgradable packages."
4062 (when-let* ((upgrades (package-menu--find-upgrades)))
4063 (message "Packages that can be upgraded: %d; type `%s' to mark for upgrading."
4064 (length upgrades)
4065 (substitute-command-keys "\\[package-menu-mark-upgrades]"))))
4066
4067
4068(defun package-menu--post-refresh ()
4069 "Revert \"*Packages*\" buffer and check for new packages and upgrades.
4070Do nothing if there's no *Packages* buffer.
4071
4072This function is called after `package-refresh-contents' and it
4073is added to `post-command-hook' by any function which alters the
4074package database (`package-install' and `package-delete'). When
4075run, it removes itself from `post-command-hook'."
4076 (remove-hook 'post-command-hook #'package-menu--post-refresh)
4077 (let ((buf (get-buffer "*Packages*")))
4078 (when (buffer-live-p buf)
4079 (with-current-buffer buf
4080 (package-menu--populate-new-package-list)
4081 (run-hooks 'tabulated-list-revert-hook)
4082 (tabulated-list-print 'remember 'update)))))
4083
4084(defun package-menu--mark-or-notify-upgrades ()
4085 "If there's a *Packages* buffer, check for upgrades and possibly mark them.
4086Do nothing if there's no *Packages* buffer. If there are
4087upgrades, mark them if `package-menu--mark-upgrades-pending' is
4088non-nil, otherwise just notify the user that there are upgrades.
4089This function is called after `package-refresh-contents'."
4090 (let ((buf (get-buffer "*Packages*")))
4091 (when (buffer-live-p buf)
4092 (with-current-buffer buf
4093 (if package-menu--mark-upgrades-pending
4094 (package-menu--mark-upgrades-1)
4095 (package-menu--find-and-notify-upgrades))))))
4096
4097;;;###autoload
4098(defun list-packages (&optional no-fetch)
4099 "Display a list of packages.
4100This first fetches the updated list of packages before
4101displaying, unless a prefix argument NO-FETCH is specified.
4102The list is displayed in a buffer named `*Packages*', and
4103includes the package's version, availability status, and a
4104short description."
4105 (interactive "P")
4106 (require 'finder-inf nil t)
4107 ;; Initialize the package system if necessary.
4108 (unless package--initialized
4109 (package-initialize t))
4110 ;; Integrate the package-menu with updating the archives.
4111 (add-hook 'package--post-download-archives-hook
4112 #'package-menu--post-refresh)
4113 (add-hook 'package--post-download-archives-hook
4114 #'package-menu--mark-or-notify-upgrades 'append)
4115 (add-hook 'package--post-download-archives-hook
4116 #'package-menu--set-mode-line-format 'append)
4117
4118 ;; Generate the Package Menu.
4119 (let ((buf (get-buffer-create "*Packages*")))
4120 (with-current-buffer buf
4121 ;; Since some packages have their descriptions include non-ASCII
4122 ;; characters...
4123 (setq buffer-file-coding-system 'utf-8)
4124 (package-menu-mode)
4125
4126 ;; Fetch the remote list of packages.
4127 (unless no-fetch (package-menu--refresh-contents))
4128
4129 ;; If we're not async, this would be redundant.
4130 (when package-menu-async
4131 (package-menu--generate nil t)))
4132 ;; The package menu buffer has keybindings. If the user types
4133 ;; `M-x list-packages', that suggests it should become current.
4134 (pop-to-buffer-same-window buf)))
4135
4136;;;###autoload
4137(defalias 'package-list-packages 'list-packages)
4138
4139;; Used in finder.el
4140(defun package-show-package-list (&optional packages keywords)
4141 "Display PACKAGES in a *Packages* buffer.
4142This is similar to `list-packages', but it does not fetch the
4143updated list of packages, and it only displays packages with
4144names in PACKAGES (which should be a list of symbols).
4145
4146When KEYWORDS are given, only packages with those KEYWORDS are
4147shown."
4148 (interactive)
4149 (require 'finder-inf nil t)
4150 (let* ((buf (get-buffer-create "*Packages*"))
4151 (win (get-buffer-window buf)))
4152 (with-current-buffer buf
4153 (package-menu-mode)
4154 (package-menu--generate nil packages keywords))
4155 (if win
4156 (select-window win)
4157 (switch-to-buffer buf))))
4158
4159(defun package-menu--filter-by (predicate suffix)
4160 "Filter \"*Packages*\" buffer by PREDICATE and add SUFFIX to header.
4161PREDICATE is a function which will be called with one argument, a
4162`package-desc' object, and returns t if that object should be
4163listed in the Package Menu.
4164
4165SUFFIX is passed on to `package-menu--display' and is added to
4166the header line of the first column."
4167 ;; Update `tabulated-list-entries' so that it contains all
4168 ;; packages before searching.
4169 (package-menu--refresh t nil)
4170 (let (found-entries)
4171 (dolist (entry tabulated-list-entries)
4172 (when (funcall predicate (car entry))
4173 (push entry found-entries)))
4174 (if found-entries
4175 (progn
4176 (setq tabulated-list-entries found-entries)
4177 (package-menu--display t suffix))
4178 (user-error "No packages found"))))
4179
4180(defun package-menu-filter-by-archive (archive)
4181 "Filter the \"*Packages*\" buffer by ARCHIVE.
4182Display only packages from package archive ARCHIVE.
4183ARCHIVE can be the name of a single archive (a string), or
4184a list of archive names. If ARCHIVE is nil or an empty
4185string, show all packages.
4186
4187When called interactively, prompt for ARCHIVE. To specify
4188several archives, type their names separated by commas."
4189 (interactive (list (completing-read-multiple
4190 "Filter by archive: "
4191 (mapcar #'car package-archives)))
4192 package-menu-mode)
4193 (package--ensure-package-menu-mode)
4194 (let ((archives (ensure-list archive)))
4195 (package-menu--filter-by
4196 (lambda (pkg-desc)
4197 (let ((pkg-archive (package-desc-archive pkg-desc)))
4198 (or (null archives)
4199 (and pkg-archive
4200 (member pkg-archive archives)))))
4201 (concat "archive:" (string-join archives ",")))))
4202
4203(defun package-menu-filter-by-description (description)
4204 "Filter the \"*Packages*\" buffer by the regexp DESCRIPTION.
4205Display only packages whose description matches the regexp
4206given as DESCRIPTION.
4207
4208When called interactively, prompt for DESCRIPTION.
4209
4210If DESCRIPTION is nil or the empty string, show all packages."
4211 (interactive (list (read-regexp "Filter by description (regexp)"))
4212 package-menu-mode)
4213 (package--ensure-package-menu-mode)
4214 (if (or (not description) (string-empty-p description))
4215 (package-menu--generate t t)
4216 (package-menu--filter-by (lambda (pkg-desc)
4217 (string-match description
4218 (package-desc-summary pkg-desc)))
4219 (format "desc:%s" description))))
4220
4221(defun package-menu-filter-by-keyword (keyword)
4222 "Filter the \"*Packages*\" buffer by KEYWORD.
4223Display only packages whose keywords match the specified KEYWORD.
4224KEYWORD can be a string or a list of strings. If KEYWORD is nil
4225or the empty string, show all packages.
4226
4227In addition to package keywords, KEYWORD can include the name(s)
4228of archive(s) and the package status, such as \"available\"
4229or \"built-in\" or \"obsolete\".
4230
4231When called interactively, prompt for KEYWORD. To specify several
4232keywords, type them separated by commas."
4233 (interactive (list (completing-read-multiple
4234 "Keywords: "
4235 (package-all-keywords)))
4236 package-menu-mode)
4237 (package--ensure-package-menu-mode)
4238 (when (stringp keyword)
4239 (setq keyword (list keyword)))
4240 (if (not keyword)
4241 (package-menu--generate t t)
4242 (package-menu--filter-by (lambda (pkg-desc)
4243 (package--has-keyword-p pkg-desc keyword))
4244 (concat "keyword:" (string-join keyword ",")))))
4245
4246(define-obsolete-function-alias
4247 'package-menu-filter #'package-menu-filter-by-keyword "27.1")
4248
4249(defun package-menu-filter-by-name-or-description (name-or-description)
4250 "Filter the \"*Packages*\" buffer by the regexp NAME-OR-DESCRIPTION.
4251Display only packages whose name or description matches the regexp
4252NAME-OR-DESCRIPTION.
4253
4254When called interactively, prompt for NAME-OR-DESCRIPTION.
4255
4256If NAME-OR-DESCRIPTION is nil or the empty string, show all
4257packages."
4258 (interactive (list (read-regexp "Filter by name or description (regexp)"))
4259 package-menu-mode)
4260 (package--ensure-package-menu-mode)
4261 (if (or (not name-or-description) (string-empty-p name-or-description))
4262 (package-menu--generate t t)
4263 (package-menu--filter-by (lambda (pkg-desc)
4264 (or (string-match name-or-description
4265 (package-desc-summary pkg-desc))
4266 (string-match name-or-description
4267 (symbol-name
4268 (package-desc-name pkg-desc)))))
4269 (format "name-or-desc:%s" name-or-description))))
4270
4271(defun package-menu-filter-by-name (name)
4272 "Filter the \"*Packages*\" buffer by the regexp NAME.
4273Display only packages whose name matches the regexp NAME.
4274
4275When called interactively, prompt for NAME.
4276
4277If NAME is nil or the empty string, show all packages."
4278 (interactive (list (read-regexp "Filter by name (regexp)"))
4279 package-menu-mode)
4280 (package--ensure-package-menu-mode)
4281 (if (or (not name) (string-empty-p name))
4282 (package-menu--generate t t)
4283 (package-menu--filter-by (lambda (pkg-desc)
4284 (string-match-p name (symbol-name
4285 (package-desc-name pkg-desc))))
4286 (format "name:%s" name))))
4287
4288(defun package-menu-filter-by-status (status)
4289 "Filter the \"*Packages*\" buffer by STATUS.
4290Display only packages with specified STATUS.
4291STATUS can be a single status, a string, or a list of strings.
4292If STATUS is nil or the empty string, show all packages.
4293
4294When called interactively, prompt for STATUS. To specify
4295several possible status values, type them separated by commas."
4296 (interactive (list (completing-read "Filter by status: "
4297 '("avail-obso"
4298 "available"
4299 "built-in"
4300 "dependency"
4301 "disabled"
4302 "external"
4303 "held"
4304 "incompat"
4305 "installed"
4306 "source"
4307 "new"
4308 "unsigned")))
4309 package-menu-mode)
4310 (package--ensure-package-menu-mode)
4311 (if (or (not status) (string-empty-p status))
4312 (package-menu--generate t t)
4313 (let ((status-list
4314 (if (listp status)
4315 status
4316 (split-string status ","))))
4317 (package-menu--filter-by
4318 (lambda (pkg-desc)
4319 (member (package-desc-status pkg-desc) status-list))
4320 (format "status:%s" (string-join status-list ","))))))
4321
4322(defun package-menu-filter-by-version (version predicate)
4323 "Filter the \"*Packages*\" buffer by VERSION and PREDICATE.
4324Display only packages whose version satisfies the condition
4325defined by VERSION and PREDICATE.
4326
4327When called interactively, prompt for one of the comparison operators
4328`<', `>' or `=', and for a version. Show only packages whose version
4329is lower (`<'), equal (`=') or higher (`>') than the specified VERSION.
4330
4331When called from Lisp, VERSION should be a version string and
4332PREDICATE should be the symbol `=', `<' or `>'.
4333
4334If VERSION is nil or the empty string, show all packages."
4335 (interactive (let ((choice (intern
4336 (char-to-string
4337 (read-char-choice
4338 "Filter by version? [Type =, <, > or q] "
4339 '(?< ?> ?= ?q))))))
4340 (if (eq choice 'q)
4341 '(quit nil)
4342 (list (read-from-minibuffer
4343 (concat "Filter by version ("
4344 (pcase choice
4345 ('= "= equal to")
4346 ('< "< less than")
4347 ('> "> greater than"))
4348 "): "))
4349 choice)))
4350 package-menu-mode)
4351 (package--ensure-package-menu-mode)
4352 (unless (equal predicate 'quit)
4353 (if (or (not version) (string-empty-p version))
4354 (package-menu--generate t t)
4355 (package-menu--filter-by
4356 (let ((fun (pcase predicate
4357 ('= #'version-list-=)
4358 ('< #'version-list-<)
4359 ('> (lambda (a b) (not (version-list-<= a b))))
4360 (_ (error "Unknown predicate: %s" predicate))))
4361 (ver (version-to-list version)))
4362 (lambda (pkg-desc)
4363 (funcall fun (package-desc-version pkg-desc) ver)))
4364 (format "versions:%s%s" predicate version)))))
4365
4366(defun package-menu-filter-marked ()
4367 "Filter \"*Packages*\" buffer by non-empty mark.
4368Show only the packages that have been marked for installation or deletion.
4369Unlike other filters, this leaves the marks intact."
4370 (interactive nil package-menu-mode)
4371 (package--ensure-package-menu-mode)
4372 (widen)
4373 (let (found-entries mark pkg-id entry marks)
4374 (save-excursion
4375 (goto-char (point-min))
4376 (while (not (eobp))
4377 (setq mark (char-after))
4378 (unless (eq mark ?\s)
4379 (setq pkg-id (tabulated-list-get-id))
4380 (setq entry (package-menu--print-info-simple pkg-id))
4381 (push entry found-entries)
4382 ;; remember the mark
4383 (push (cons pkg-id mark) marks))
4384 (forward-line))
4385 (if found-entries
4386 (progn
4387 (setq tabulated-list-entries found-entries)
4388 (package-menu--display t nil)
4389 ;; redo the marks, but we must remember the marks!!
4390 (goto-char (point-min))
4391 (while (not (eobp))
4392 (setq mark (cdr (assq (tabulated-list-get-id) marks)))
4393 (tabulated-list-put-tag (char-to-string mark) t)))
4394 (user-error "No packages found")))))
4395
4396(defun package-menu-filter-upgradable ()
4397 "Filter \"*Packages*\" buffer to show only upgradable packages."
4398 (interactive nil package-menu-mode)
4399 (let ((pkgs (mapcar #'car (package-menu--find-upgrades))))
4400 (package-menu--filter-by
4401 (lambda (pkg)
4402 (memql (package-desc-name pkg) pkgs))
4403 "upgradable")))
4404
4405(defun package-menu-clear-filter ()
4406 "Clear any filter currently applied to the \"*Packages*\" buffer."
4407 (interactive nil package-menu-mode)
4408 (package--ensure-package-menu-mode)
4409 (package-menu--generate t t))
4410
4411(defun package-list-packages-no-fetch ()
4412 "Display a list of packages.
4413Does not fetch the updated list of packages before displaying.
4414The list is displayed in a buffer named `*Packages*'."
4415 (interactive)
4416 (list-packages t))
4417
4418
4419;;;; Quickstart: precompute activation actions for faster start up.
4420
4421;; Activating packages via `package-initialize' is costly: for N installed
4422;; packages, it needs to read all N <pkg>-pkg.el files first to decide
4423;; which packages to activate, and then again N <pkg>-autoloads.el files.
4424;; To speed this up, we precompute a mega-autoloads file which is the
4425;; concatenation of all those <pkg>-autoloads.el, so we can activate
4426;; all packages by loading this one file (and hence without initializing
4427;; package.el).
4428
4429;; Other than speeding things up, this also offers a bootstrap feature:
4430;; it lets us activate packages according to `package-load-list' and
4431;; `package-user-dir' even before those vars are set.
4432
4433(defcustom package-quickstart nil
4434 "Precompute activation actions to speed up startup.
4435This requires the use of `package-quickstart-refresh' every time the
4436activations need to be changed, such as when `package-load-list' is modified."
4437 :type 'boolean
4438 :version "27.1")
4439
4440;;;###autoload
4441(defcustom package-quickstart-file
4442 (locate-user-emacs-file "package-quickstart.el")
4443 "Location of the file used to speed up activation of packages at startup."
4444 :type 'file
4445 :group 'applications
4446 :initialize #'custom-initialize-delay
4447 :version "27.1")
4448
4449(defun package--quickstart-maybe-refresh ()
4450 (if package-quickstart
4451 ;; FIXME: Delay refresh in case we're installing/deleting
4452 ;; several packages!
4453 (package-quickstart-refresh)
4454 (delete-file (concat package-quickstart-file "c"))
4455 (delete-file package-quickstart-file)))
4456
4457(defvar package--quickstart-dir nil
4458 "Set by `package-quickstart-file' to the directory containing it.")
4459
4460(defun package--quickstart-rel (file)
4461 "Return an expr depending on `package--quickstart-dir' which evaluates to FILE.
4462
4463If FILE is in `package--quickstart-dir', returns an expression that is
4464relative to that directory, so if that directory is moved we can still
4465find FILE."
4466 (if (file-in-directory-p file package--quickstart-dir)
4467 `(file-name-concat package--quickstart-dir ,(file-relative-name file package--quickstart-dir))
4468 file))
4469
4470(defun package-quickstart-refresh ()
4471 "(Re)Generate the `package-quickstart-file'."
4472 (interactive)
4473 (package-initialize 'no-activate)
4474 (require 'info)
4475 (let ((package--quickstart-pkgs ())
4476 ;; Pretend we haven't activated anything yet!
4477 (package-activated-list ())
4478 ;; Make sure we can load this file without load-source-file-function.
4479 (coding-system-for-write 'emacs-internal)
4480 ;; Ensure that `pp' and `prin1-to-string' calls further down
4481 ;; aren't truncated.
4482 (print-length nil)
4483 (print-level nil)
4484 (Info-directory-list '(""))
4485 (package--quickstart-dir nil))
4486 (dolist (elt package-alist)
4487 (condition-case err
4488 (package-activate (car elt))
4489 ;; Don't let failure of activation of a package arbitrarily stop
4490 ;; activation of further packages.
4491 (error (message "%s" (error-message-string err)))))
4492 (setq package--quickstart-pkgs (nreverse package--quickstart-pkgs))
4493 (with-temp-file package-quickstart-file
4494 (emacs-lisp-mode) ;For `syntax-ppss'.
4495 (insert ";;; Quickstart file to activate all packages at startup -*- lexical-binding:t -*-\n")
4496 (insert ";; ¡¡ This file is autogenerated by `package-quickstart-refresh', DO NOT EDIT !!\n\n")
4497 (setq package--quickstart-dir
4498 (file-name-directory (expand-file-name package-quickstart-file)))
4499 (pp '(setq package--quickstart-dir
4500 (file-name-directory (expand-file-name load-file-name)))
4501 (current-buffer))
4502 (dolist (pkg package--quickstart-pkgs)
4503 (let* ((file
4504 ;; Prefer uncompiled files (and don't accept .so files).
4505 (let ((load-suffixes '(".el" ".elc")))
4506 (locate-library (package--autoloads-file-name pkg))))
4507 (pfile (prin1-to-string (package--quickstart-rel file))))
4508 (insert "(let* ((load-file-name " pfile ")\
4509\(load-true-file-name load-file-name))\n")
4510 (insert-file-contents file)
4511 ;; Fixup the special #$ reader form and throw away comments.
4512 (while (re-search-forward "#\\$\\|^;\\(.*\n\\)" nil 'move)
4513 (unless (ppss-string-terminator (save-match-data (syntax-ppss)))
4514 (replace-match (if (match-end 1) "" pfile) t t)))
4515 (unless (bolp) (insert "\n"))
4516 (insert ")\n")))
4517 (pp `(defvar package-activated-list) (current-buffer))
4518 (pp `(setq package-activated-list
4519 (delete-dups
4520 (append ',(mapcar #'package-desc-name package--quickstart-pkgs)
4521 package-activated-list)))
4522 (current-buffer))
4523 (let ((info-dirs
4524 (mapcar #'package--quickstart-rel (butlast Info-directory-list))))
4525 (when info-dirs
4526 (pp `(progn (require 'info)
4527 (info-initialize)
4528 (setq Info-directory-list
4529 (append (list . ,info-dirs) Info-directory-list)))
4530 (current-buffer))))
4531 ;; Use `\s' instead of a space character, so this code chunk is not
4532 ;; mistaken for an actual file-local section of package.el.
4533 (insert "
4534;; Local\sVariables:
4535;; version-control: never
4536;; no-update-autoloads: t
4537;; byte-compile-warnings: (not make-local)
4538;; End:
4539"))
4540 ;; FIXME: Do it asynchronously in an Emacs subprocess, and
4541 ;; don't show the byte-compiler warnings.
4542 (byte-compile-file package-quickstart-file)))
4543
4544(defun package--imenu-prev-index-position-function ()
4545 "Move point to previous line in package-menu buffer.
4546This function is used as a value for
4547`imenu-prev-index-position-function'."
4548 (unless (bobp)
4549 (forward-line -1)))
4550
4551(defun package--imenu-extract-index-name-function ()
4552 "Return imenu name for line at point.
4553This function is used as a value for
4554`imenu-extract-index-name-function'. Point should be at the
4555beginning of the line."
4556 (let ((package-desc (tabulated-list-get-id)))
4557 (format "%s (%s): %s"
4558 (package-desc-name package-desc)
4559 (package-version-join (package-desc-version package-desc))
4560 (package-desc-summary package-desc))))
4561
4562(defun package--query-desc (&optional alist)
4563 "Query the user for a package or return the package at point.
4564The optional argument ALIST must consist of elements with the
4565form (PKG-NAME PKG-DESC). If not specified, it will default to
4566`package-alist'."
4567 (or (tabulated-list-get-id)
4568 (let ((alist (or alist package-alist)))
4569 (cadr (assoc (completing-read "Package: " alist nil t)
4570 alist #'string=)))))
4571
4572(defun package-browse-url (desc &optional secondary)
4573 "Open the website of the package under point in a browser.
4574`browse-url' is used to determine the browser to be used. If
4575SECONDARY (interactively, the prefix), use the secondary browser.
4576DESC must be a `package-desc' object."
4577 (interactive (list (package--query-desc)
4578 current-prefix-arg)
4579 package-menu-mode)
4580 (unless desc
4581 (user-error "No package here"))
4582 (let ((url (cdr (assoc :url (package-desc-extras desc)))))
4583 (unless url
4584 (user-error "No website for %s" (package-desc-name desc)))
4585 (if secondary
4586 (funcall browse-url-secondary-browser-function url)
4587 (browse-url url))))
4588
4589(declare-function ietf-drums-parse-address "ietf-drums"
4590 (string &optional decode))
4591
4592(defun package-maintainers (pkg-desc &optional no-error)
4593 "Return an email address for the maintainers of PKG-DESC.
4594The email address may contain commas, if there are multiple
4595maintainers. If no maintainers are found, an error will be
4596signaled. If the optional argument NO-ERROR is non-nil no error
4597will be signaled in that case."
4598 (unless (package-desc-p pkg-desc)
4599 (error "Invalid package description: %S" pkg-desc))
4600 (let* ((name (package-desc-name pkg-desc))
4601 (extras (package-desc-extras pkg-desc))
4602 (maint (alist-get :maintainer extras)))
4603 (unless (listp (cdr maint))
4604 (setq maint (list maint)))
4605 (cond
4606 ((and (null maint) (null no-error))
4607 (user-error "Package `%s' has no explicit maintainer" name))
4608 ((and (not (progn
4609 (require 'ietf-drums)
4610 (ietf-drums-parse-address (cdar maint))))
4611 (null no-error))
4612 (user-error "Package `%s' has no maintainer address" name))
4613 (t
4614 (with-temp-buffer
4615 (mapc #'package--print-email-button maint)
4616 (replace-regexp-in-string
4617 "\n" ", " (string-trim
4618 (buffer-substring-no-properties
4619 (point-min) (point-max)))))))))
4620
4621;;;###autoload
4622(defun package-report-bug (desc)
4623 "Prepare a message to send to the maintainers of a package.
4624DESC must be a `package-desc' object."
4625 (interactive (list (package--query-desc package-alist))
4626 package-menu-mode)
4627 (let ((maint (package-maintainers desc))
4628 (name (symbol-name (package-desc-name desc)))
4629 (pkgdir (package-desc-dir desc))
4630 vars)
4631 (when pkgdir
4632 (dolist-with-progress-reporter (group custom-current-group-alist)
4633 "Scanning for modified user options..."
4634 (when (and (car group)
4635 (file-in-directory-p (car group) pkgdir))
4636 (dolist (ent (get (cdr group) 'custom-group))
4637 (when (and (custom-variable-p (car ent))
4638 (boundp (car ent))
4639 (not (eq (custom--standard-value (car ent))
4640 (default-toplevel-value (car ent)))))
4641 (push (car ent) vars))))))
4642 (dlet ((reporter-prompt-for-summary-p t))
4643 (reporter-submit-bug-report maint name vars))))
4644
4645;;;; Introspection
4646
4647(defun package-get-descriptor (pkg-name)
4648 "Return the `package-desc' of PKG-NAME."
4649 (unless package--initialized (package-initialize 'no-activate))
4650 (or (package--get-activatable-pkg pkg-name)
4651 (cadr (assq pkg-name package-alist))
4652 (cadr (assq pkg-name package-archive-contents))))
4653
4654(provide 'package)
4655
4656;;; package.el ends here