diff options
| author | Stefan Monnier | 2013-06-13 23:20:18 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2013-06-13 23:20:18 -0400 |
| commit | 1b8dff239bf8091a75572064ff8fb085f3c073d6 (patch) | |
| tree | d3f518d514fef3fc8eb54e36cccd25c083d32bd1 | |
| parent | 0b31660d3c10a0f8e243dd67bd0ecaf2c847d1e6 (diff) | |
| download | emacs-1b8dff239bf8091a75572064ff8fb085f3c073d6.tar.gz emacs-1b8dff239bf8091a75572064ff8fb085f3c073d6.zip | |
* lisp/emacs-lisp/package.el: Don't recompute dir. Use pkg-descs more.
(package-desc): Add `dir' field.
(package-desc-full-name): New function.
(package-load-descriptor): Combine the two arguments. Don't use `load'.
(package-maybe-load-descriptor): Remove.
(package-load-all-descriptors): Just call package-load-descriptor.
(package--disabled-p): New function.
(package-desc-vers, package-desc-doc): Remove aliases.
(package--dir): Remove function.
(package-activate): Check if a package is disabled.
(package-process-define-package): New function, extracted from
define-package.
(define-package): Turn into a place holder.
(package-unpack-single, package-tar-file-info):
Use package--description-file.
(package-compute-transaction): Use package--disabled-p.
(package-download-transaction): Don't call
package-maybe-load-descriptor since they're all loaded anyway.
(package-install): Change argument to be a pkg-desc.
(package-delete): Use a single pkg-desc argument.
(describe-package-1): Use package-desc-dir instead of package--dir.
Use package-desc property instead of package-symbol.
(package-install-button-action): Adjust accordingly.
(package--push): Rewrite.
(package-menu--print-info): Adjust accordingly. Change the ID format
to be a pkg-desc.
(package-menu-describe-package, package-menu-get-status)
(package-menu--find-upgrades, package-menu-mark-upgrades)
(package-menu-execute, package-menu--name-predicate):
Adjust accordingly.
* lisp/startup.el (package--description-file): New function.
(command-line): Use it.
* lisp/emacs-lisp/package-x.el (package-upload-buffer-internal):
Use package-desc-version.
| -rw-r--r-- | lisp/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package-x.el | 2 | ||||
| -rw-r--r-- | lisp/emacs-lisp/package.el | 417 | ||||
| -rw-r--r-- | lisp/startup.el | 15 |
4 files changed, 243 insertions, 226 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 875a361f57b..67e361cc320 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,40 @@ | |||
| 1 | 2013-06-14 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2013-06-14 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * emacs-lisp/package.el: Don't recompute dir. Use pkg-descs more. | ||
| 4 | (package-desc): Add `dir' field. | ||
| 5 | (package-desc-full-name): New function. | ||
| 6 | (package-load-descriptor): Combine the two arguments. Don't use `load'. | ||
| 7 | (package-maybe-load-descriptor): Remove. | ||
| 8 | (package-load-all-descriptors): Just call package-load-descriptor. | ||
| 9 | (package--disabled-p): New function. | ||
| 10 | (package-desc-vers, package-desc-doc): Remove aliases. | ||
| 11 | (package--dir): Remove function. | ||
| 12 | (package-activate): Check if a package is disabled. | ||
| 13 | (package-process-define-package): New function, extracted from | ||
| 14 | define-package. | ||
| 15 | (define-package): Turn into a place holder. | ||
| 16 | (package-unpack-single, package-tar-file-info): | ||
| 17 | Use package--description-file. | ||
| 18 | (package-compute-transaction): Use package--disabled-p. | ||
| 19 | (package-download-transaction): Don't call | ||
| 20 | package-maybe-load-descriptor since they're all loaded anyway. | ||
| 21 | (package-install): Change argument to be a pkg-desc. | ||
| 22 | (package-delete): Use a single pkg-desc argument. | ||
| 23 | (describe-package-1): Use package-desc-dir instead of package--dir. | ||
| 24 | Use package-desc property instead of package-symbol. | ||
| 25 | (package-install-button-action): Adjust accordingly. | ||
| 26 | (package--push): Rewrite. | ||
| 27 | (package-menu--print-info): Adjust accordingly. Change the ID format | ||
| 28 | to be a pkg-desc. | ||
| 29 | (package-menu-describe-package, package-menu-get-status) | ||
| 30 | (package-menu--find-upgrades, package-menu-mark-upgrades) | ||
| 31 | (package-menu-execute, package-menu--name-predicate): | ||
| 32 | Adjust accordingly. | ||
| 33 | * startup.el (package--description-file): New function. | ||
| 34 | (command-line): Use it. | ||
| 35 | * emacs-lisp/package-x.el (package-upload-buffer-internal): | ||
| 36 | Use package-desc-version. | ||
| 37 | |||
| 3 | * emacs-lisp/bytecomp.el (byte-compile-force-lexical-warnings): New var. | 38 | * emacs-lisp/bytecomp.el (byte-compile-force-lexical-warnings): New var. |
| 4 | (byte-compile-preprocess): Use it. | 39 | (byte-compile-preprocess): Use it. |
| 5 | (byte-compile-file-form-defalias): Try a bit harder to use macros we | 40 | (byte-compile-file-form-defalias): Try a bit harder to use macros we |
diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index 17919d9bbeb..3300e89ec1e 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el | |||
| @@ -224,7 +224,7 @@ if it exists." | |||
| 224 | (let ((elt (assq pkg-name (cdr contents)))) | 224 | (let ((elt (assq pkg-name (cdr contents)))) |
| 225 | (if elt | 225 | (if elt |
| 226 | (if (version-list-<= split-version | 226 | (if (version-list-<= split-version |
| 227 | (package-desc-vers (cdr elt))) | 227 | (package-desc-version (cdr elt))) |
| 228 | (error "New package has smaller version: %s" pkg-version) | 228 | (error "New package has smaller version: %s" pkg-version) |
| 229 | (setcdr elt new-desc)) | 229 | (setcdr elt new-desc)) |
| 230 | (setq contents (cons (car contents) | 230 | (setq contents (cons (car contents) |
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index d5176abded0..6d34c229733 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el | |||
| @@ -336,13 +336,22 @@ required version. | |||
| 336 | either `single' or `tar'. | 336 | either `single' or `tar'. |
| 337 | 337 | ||
| 338 | `archive' The name of the archive (as a string) whence this | 338 | `archive' The name of the archive (as a string) whence this |
| 339 | package came." | 339 | package came. |
| 340 | |||
| 341 | `dir' The directory where the package is installed (if installed)." | ||
| 340 | name | 342 | name |
| 341 | version | 343 | version |
| 342 | (summary package--default-summary) | 344 | (summary package--default-summary) |
| 343 | reqs | 345 | reqs |
| 344 | kind | 346 | kind |
| 345 | archive) | 347 | archive |
| 348 | dir) | ||
| 349 | |||
| 350 | ;; Pseudo fields. | ||
| 351 | (defsubst package-desc-full-name (pkg-desc) | ||
| 352 | (format "%s-%s" | ||
| 353 | (package-desc-name pkg-desc) | ||
| 354 | (package-version-join (package-desc-version pkg-desc)))) | ||
| 346 | 355 | ||
| 347 | ;; Package descriptor format used in finder-inf.el and package--builtins. | 356 | ;; Package descriptor format used in finder-inf.el and package--builtins. |
| 348 | (cl-defstruct (package--bi-desc | 357 | (cl-defstruct (package--bi-desc |
| @@ -422,17 +431,18 @@ E.g., if given \"quux-23.0\", will return \"quux\"" | |||
| 422 | (if (string-match (concat "\\`" package-subdirectory-regexp "\\'") dirname) | 431 | (if (string-match (concat "\\`" package-subdirectory-regexp "\\'") dirname) |
| 423 | (match-string 1 dirname))) | 432 | (match-string 1 dirname))) |
| 424 | 433 | ||
| 425 | (defun package-load-descriptor (dir package) | 434 | (defun package-load-descriptor (pkg-dir) |
| 426 | "Load the description file in directory DIR for package PACKAGE. | 435 | "Load the description file in directory PKG-DIR." |
| 427 | Here, PACKAGE is a string of the form NAME-VERSION, where NAME is | 436 | (let ((pkg-file (expand-file-name (package--description-file pkg-dir) |
| 428 | the package name and VERSION is its version." | 437 | pkg-dir))) |
| 429 | (let* ((pkg-dir (expand-file-name package dir)) | 438 | (when (file-exists-p pkg-file) |
| 430 | (pkg-file (expand-file-name | 439 | (with-temp-buffer |
| 431 | (concat (package-strip-version package) "-pkg") | 440 | (insert-file-contents pkg-file) |
| 432 | pkg-dir))) | 441 | (emacs-lisp-mode) |
| 433 | (when (and (file-directory-p pkg-dir) | 442 | (goto-char (point-min)) |
| 434 | (file-exists-p (concat pkg-file ".el"))) | 443 | (let ((pkg-desc (package-process-define-package |
| 435 | (load pkg-file nil t)))) | 444 | (read (current-buffer)) pkg-file))) |
| 445 | (setf (package-desc-dir pkg-desc) pkg-dir)))))) | ||
| 436 | 446 | ||
| 437 | (defun package-load-all-descriptors () | 447 | (defun package-load-all-descriptors () |
| 438 | "Load descriptors for installed Emacs Lisp packages. | 448 | "Load descriptors for installed Emacs Lisp packages. |
| @@ -443,65 +453,34 @@ controls which package subdirectories may be loaded. | |||
| 443 | In each valid package subdirectory, this function loads the | 453 | In each valid package subdirectory, this function loads the |
| 444 | description file containing a call to `define-package', which | 454 | description file containing a call to `define-package', which |
| 445 | updates `package-alist' and `package-obsolete-alist'." | 455 | updates `package-alist' and `package-obsolete-alist'." |
| 446 | (let ((regexp (concat "\\`" package-subdirectory-regexp "\\'"))) | 456 | (dolist (dir (cons package-user-dir package-directory-list)) |
| 447 | (dolist (dir (cons package-user-dir package-directory-list)) | 457 | (when (file-directory-p dir) |
| 448 | (when (file-directory-p dir) | 458 | (dolist (subdir (directory-files dir)) |
| 449 | (dolist (subdir (directory-files dir)) | 459 | (let ((pkg-dir (expand-file-name subdir dir))) |
| 450 | (when (string-match regexp subdir) | 460 | (when (file-directory-p pkg-dir) |
| 451 | (package-maybe-load-descriptor (match-string 1 subdir) | 461 | (package-load-descriptor pkg-dir))))))) |
| 452 | (match-string 2 subdir) | 462 | |
| 453 | dir))))))) | 463 | (defun package-disabled-p (pkg-name version) |
| 454 | 464 | "Return whether PKG-NAME at VERSION can be activated. | |
| 455 | (defun package-maybe-load-descriptor (name version dir) | 465 | The decision is made according to `package-load-list'. |
| 456 | "Maybe load a specific package from directory DIR. | 466 | Return nil if the package can be activated. |
| 457 | NAME and VERSION are the package's name and version strings. | 467 | Return t if the package is completely disabled. |
| 458 | This function checks `package-load-list', before actually loading | 468 | Return the max version (as a string) if the package is held at a lower version." |
| 459 | the package by calling `package-load-descriptor'." | 469 | (let ((force (assq pkg-name package-load-list))) |
| 460 | (let ((force (assq (intern name) package-load-list)) | 470 | (cond ((null force) (not (memq 'all package-load-list))) |
| 461 | (subdir (concat name "-" version))) | 471 | ((null (setq force (cadr force))) t) ; disabled |
| 462 | (and (file-directory-p (expand-file-name subdir dir)) | 472 | ((eq force t) nil) |
| 463 | ;; Check `package-load-list': | 473 | ((stringp force) ; held |
| 464 | (cond ((null force) | 474 | (unless (version-list-= version (version-to-list force)) |
| 465 | (memq 'all package-load-list)) | 475 | force)) |
| 466 | ((null (setq force (cadr force))) | 476 | (t (error "Invalid element in `package-load-list'"))))) |
| 467 | nil) ; disabled | ||
| 468 | ((eq force t) | ||
| 469 | t) | ||
| 470 | ((stringp force) ; held | ||
| 471 | (version-list-= (version-to-list version) | ||
| 472 | (version-to-list force))) | ||
| 473 | (t | ||
| 474 | (error "Invalid element in `package-load-list'"))) | ||
| 475 | ;; Actually load the descriptor: | ||
| 476 | (package-load-descriptor dir subdir)))) | ||
| 477 | |||
| 478 | (define-obsolete-function-alias 'package-desc-vers 'package-desc-version "24.4") | ||
| 479 | |||
| 480 | (define-obsolete-function-alias 'package-desc-doc 'package-desc-summary "24.4") | ||
| 481 | |||
| 482 | |||
| 483 | (defun package--dir (name version) | ||
| 484 | ;; FIXME: Keep this as a field in the package-desc. | ||
| 485 | "Return the directory where a package is installed, or nil if none. | ||
| 486 | NAME is a symbol and VERSION is a string." | ||
| 487 | (let* ((subdir (format "%s-%s" name version)) | ||
| 488 | (dir-list (cons package-user-dir package-directory-list)) | ||
| 489 | pkg-dir) | ||
| 490 | (while dir-list | ||
| 491 | (let ((subdir-full (expand-file-name subdir (car dir-list)))) | ||
| 492 | (if (file-directory-p subdir-full) | ||
| 493 | (setq pkg-dir subdir-full | ||
| 494 | dir-list nil) | ||
| 495 | (setq dir-list (cdr dir-list))))) | ||
| 496 | pkg-dir)) | ||
| 497 | 477 | ||
| 498 | (defun package-activate-1 (pkg-desc) | 478 | (defun package-activate-1 (pkg-desc) |
| 499 | (let* ((name (package-desc-name pkg-desc)) | 479 | (let* ((name (package-desc-name pkg-desc)) |
| 500 | (version-str (package-version-join (package-desc-version pkg-desc))) | 480 | (pkg-dir (package-desc-dir pkg-desc))) |
| 501 | (pkg-dir (package--dir name version-str))) | ||
| 502 | (unless pkg-dir | 481 | (unless pkg-dir |
| 503 | (error "Internal error: unable to find directory for `%s-%s'" | 482 | (error "Internal error: unable to find directory for `%s'" |
| 504 | name version-str)) | 483 | (package-desc-full-name pkg-desc))) |
| 505 | ;; Add info node. | 484 | ;; Add info node. |
| 506 | (when (file-exists-p (expand-file-name "dir" pkg-dir)) | 485 | (when (file-exists-p (expand-file-name "dir" pkg-dir)) |
| 507 | ;; FIXME: not the friendliest, but simple. | 486 | ;; FIXME: not the friendliest, but simple. |
| @@ -553,6 +532,8 @@ Return nil if the package could not be activated." | |||
| 553 | ;; If the package is already activated, just return t. | 532 | ;; If the package is already activated, just return t. |
| 554 | ((memq package package-activated-list) | 533 | ((memq package package-activated-list) |
| 555 | t) | 534 | t) |
| 535 | ;; If it's disabled, then just skip it. | ||
| 536 | ((package-disabled-p package available-version) nil) | ||
| 556 | ;; Otherwise, proceed with activation. | 537 | ;; Otherwise, proceed with activation. |
| 557 | (t | 538 | (t |
| 558 | (let ((fail (catch 'dep-failure | 539 | (let ((fail (catch 'dep-failure |
| @@ -593,29 +574,32 @@ REQUIREMENTS is a list of dependencies on other packages. | |||
| 593 | where OTHER-VERSION is a string. | 574 | where OTHER-VERSION is a string. |
| 594 | 575 | ||
| 595 | EXTRA-PROPERTIES is currently unused." | 576 | EXTRA-PROPERTIES is currently unused." |
| 596 | (let* ((name (intern name-string)) | 577 | ;; FIXME: Placeholder! Should we keep it? |
| 597 | (version (version-to-list version-string)) | 578 | (error "Don't call me!")) |
| 598 | (new-pkg-desc (cons name | 579 | |
| 599 | (package-desc-from-define name-string | 580 | (defun package-process-define-package (exp origin) |
| 600 | version-string | 581 | (unless (eq (car-safe exp) 'define-package) |
| 601 | docstring | 582 | (error "Can't find define-package in %s" origin)) |
| 602 | requirements))) | 583 | (let* ((new-pkg-desc (apply #'package-desc-from-define (cdr exp))) |
| 603 | (old-pkg (assq name package-alist))) | 584 | (name (package-desc-name new-pkg-desc)) |
| 585 | (version (package-desc-version new-pkg-desc)) | ||
| 586 | (old-pkg (assq name package-alist))) | ||
| 604 | (cond | 587 | (cond |
| 605 | ;; If there's no old package, just add this to `package-alist'. | 588 | ;; If there's no old package, just add this to `package-alist'. |
| 606 | ((null old-pkg) | 589 | ((null old-pkg) |
| 607 | (push new-pkg-desc package-alist)) | 590 | (push (cons name new-pkg-desc) package-alist)) |
| 608 | ((version-list-< (package-desc-version (cdr old-pkg)) version) | 591 | ((version-list-< (package-desc-version (cdr old-pkg)) version) |
| 609 | ;; Remove the old package and declare it obsolete. | 592 | ;; Remove the old package and declare it obsolete. |
| 610 | (package-mark-obsolete name (cdr old-pkg)) | 593 | (package-mark-obsolete name (cdr old-pkg)) |
| 611 | (setq package-alist (cons new-pkg-desc | 594 | (setq package-alist (cons (cons name new-pkg-desc) |
| 612 | (delq old-pkg package-alist)))) | 595 | (delq old-pkg package-alist)))) |
| 613 | ;; You can have two packages with the same version, e.g. one in | 596 | ;; You can have two packages with the same version, e.g. one in |
| 614 | ;; the system package directory and one in your private | 597 | ;; the system package directory and one in your private |
| 615 | ;; directory. We just let the first one win. | 598 | ;; directory. We just let the first one win. |
| 616 | ((not (version-list-= (package-desc-version (cdr old-pkg)) version)) | 599 | ((not (version-list-= (package-desc-version (cdr old-pkg)) version)) |
| 617 | ;; The package is born obsolete. | 600 | ;; The package is born obsolete. |
| 618 | (package-mark-obsolete name (cdr new-pkg-desc)))))) | 601 | (package-mark-obsolete name new-pkg-desc))) |
| 602 | new-pkg-desc)) | ||
| 619 | 603 | ||
| 620 | ;; From Emacs 22. | 604 | ;; From Emacs 22. |
| 621 | (defun package-autoload-ensure-default-file (file) | 605 | (defun package-autoload-ensure-default-file (file) |
| @@ -711,7 +695,8 @@ PKG-DIR is the name of the package directory." | |||
| 711 | (version-to-list version))) | 695 | (version-to-list version))) |
| 712 | package-user-dir)) | 696 | package-user-dir)) |
| 713 | (el-file (expand-file-name (format "%s.el" name) pkg-dir)) | 697 | (el-file (expand-file-name (format "%s.el" name) pkg-dir)) |
| 714 | (pkg-file (expand-file-name (format "%s-pkg.el" name) pkg-dir))) | 698 | (pkg-file (expand-file-name (package--description-file pkg-dir) |
| 699 | pkg-dir))) | ||
| 715 | (make-directory pkg-dir t) | 700 | (make-directory pkg-dir t) |
| 716 | (package--write-file-no-coding el-file) | 701 | (package--write-file-no-coding el-file) |
| 717 | (let ((print-level nil) | 702 | (let ((print-level nil) |
| @@ -828,20 +813,15 @@ not included in this list." | |||
| 828 | ;; A package is required, but not installed. It might also be | 813 | ;; A package is required, but not installed. It might also be |
| 829 | ;; blocked via `package-load-list'. | 814 | ;; blocked via `package-load-list'. |
| 830 | (let ((pkg-desc (cdr (assq next-pkg package-archive-contents))) | 815 | (let ((pkg-desc (cdr (assq next-pkg package-archive-contents))) |
| 831 | hold) | 816 | (disabled (package-disabled-p next-pkg next-version))) |
| 832 | (when (setq hold (assq next-pkg package-load-list)) | 817 | (when disabled |
| 833 | (setq hold (cadr hold)) | 818 | (if (stringp disabled) |
| 834 | (cond ((eq hold t)) | 819 | (error "Package `%s' held at version %s, \ |
| 835 | ((eq hold nil) | ||
| 836 | (error "Required package '%s' is disabled" | ||
| 837 | (symbol-name next-pkg))) | ||
| 838 | ((null (stringp hold)) | ||
| 839 | (error "Invalid element in `package-load-list'")) | ||
| 840 | ((version-list-< (version-to-list hold) next-version) | ||
| 841 | (error "Package `%s' held at version %s, \ | ||
| 842 | but version %s required" | 820 | but version %s required" |
| 843 | (symbol-name next-pkg) hold | 821 | (symbol-name next-pkg) disabled |
| 844 | (package-version-join next-version))))) | 822 | (package-version-join next-version)) |
| 823 | (error "Required package '%s' is disabled" | ||
| 824 | (symbol-name next-pkg)))) | ||
| 845 | (unless pkg-desc | 825 | (unless pkg-desc |
| 846 | (error "Package `%s-%s' is unavailable" | 826 | (error "Package `%s-%s' is unavailable" |
| 847 | (symbol-name next-pkg) | 827 | (symbol-name next-pkg) |
| @@ -954,6 +934,7 @@ PACKAGE-LIST should be a list of package names (symbols). | |||
| 954 | This function assumes that all package requirements in | 934 | This function assumes that all package requirements in |
| 955 | PACKAGE-LIST are satisfied, i.e. that PACKAGE-LIST is computed | 935 | PACKAGE-LIST are satisfied, i.e. that PACKAGE-LIST is computed |
| 956 | using `package-compute-transaction'." | 936 | using `package-compute-transaction'." |
| 937 | ;; FIXME: make package-list a list of pkg-desc. | ||
| 957 | (dolist (elt package-list) | 938 | (dolist (elt package-list) |
| 958 | (let* ((desc (cdr (assq elt package-archive-contents))) | 939 | (let* ((desc (cdr (assq elt package-archive-contents))) |
| 959 | ;; As an exception, if package is "held" in | 940 | ;; As an exception, if package is "held" in |
| @@ -974,15 +955,13 @@ using `package-compute-transaction'." | |||
| 974 | ;; If package A depends on package B, then A may `require' B | 955 | ;; If package A depends on package B, then A may `require' B |
| 975 | ;; during byte compilation. So we need to activate B before | 956 | ;; during byte compilation. So we need to activate B before |
| 976 | ;; unpacking A. | 957 | ;; unpacking A. |
| 977 | (package-maybe-load-descriptor (symbol-name elt) v-string | ||
| 978 | package-user-dir) | ||
| 979 | (package-activate elt (version-to-list v-string))))) | 958 | (package-activate elt (version-to-list v-string))))) |
| 980 | 959 | ||
| 981 | ;;;###autoload | 960 | ;;;###autoload |
| 982 | (defun package-install (name) | 961 | (defun package-install (pkg-desc) |
| 983 | "Install the package named NAME. | 962 | "Install the package PKG-DESC. |
| 984 | NAME should be the name of one of the available packages in an | 963 | PKG-DESC should be one of the available packages in an |
| 985 | archive in `package-archives'. Interactively, prompt for NAME." | 964 | archive in `package-archives'. Interactively, prompt for its name." |
| 986 | (interactive | 965 | (interactive |
| 987 | (progn | 966 | (progn |
| 988 | ;; Initialize the package system to get the list of package | 967 | ;; Initialize the package system to get the list of package |
| @@ -991,20 +970,22 @@ archive in `package-archives'. Interactively, prompt for NAME." | |||
| 991 | (package-initialize t)) | 970 | (package-initialize t)) |
| 992 | (unless package-archive-contents | 971 | (unless package-archive-contents |
| 993 | (package-refresh-contents)) | 972 | (package-refresh-contents)) |
| 994 | (list (intern (completing-read | 973 | (let* ((name (intern (completing-read |
| 995 | "Install package: " | 974 | "Install package: " |
| 996 | (mapcar (lambda (elt) | 975 | (mapcar (lambda (elt) |
| 997 | (cons (symbol-name (car elt)) | 976 | (cons (symbol-name (car elt)) |
| 998 | nil)) | 977 | nil)) |
| 999 | package-archive-contents) | 978 | package-archive-contents) |
| 1000 | nil t))))) | 979 | nil t))) |
| 1001 | (let ((pkg-desc (assq name package-archive-contents))) | 980 | (pkg-desc (cdr (assq name package-archive-contents)))) |
| 1002 | (unless pkg-desc | 981 | (unless pkg-desc |
| 1003 | (error "Package `%s' is not available for installation" | 982 | (error "Package `%s' is not available for installation" |
| 1004 | (symbol-name name))) | 983 | name)) |
| 1005 | (package-download-transaction | 984 | (list pkg-desc)))) |
| 1006 | (package-compute-transaction (list name) | 985 | (package-download-transaction |
| 1007 | (package-desc-reqs (cdr pkg-desc)))))) | 986 | ;; FIXME: Use (list pkg-desc) instead of just the name. |
| 987 | (package-compute-transaction (list (package-desc-name pkg-desc)) | ||
| 988 | (package-desc-reqs pkg-desc)))) | ||
| 1008 | 989 | ||
| 1009 | (defun package-strip-rcs-id (str) | 990 | (defun package-strip-rcs-id (str) |
| 1010 | "Strip RCS version ID from the version string STR. | 991 | "Strip RCS version ID from the version string STR. |
| @@ -1055,31 +1036,28 @@ boundaries." | |||
| 1055 | "Find package information for a tar file. | 1036 | "Find package information for a tar file. |
| 1056 | FILE is the name of the tar file to examine. | 1037 | FILE is the name of the tar file to examine. |
| 1057 | The return result is a vector like `package-buffer-info'." | 1038 | The return result is a vector like `package-buffer-info'." |
| 1058 | (let ((default-directory (file-name-directory file)) | 1039 | (let* ((default-directory (file-name-directory file)) |
| 1059 | (file (file-name-nondirectory file))) | 1040 | (file (file-name-nondirectory file)) |
| 1060 | (unless (string-match (concat "\\`" package-subdirectory-regexp "\\.tar\\'") | 1041 | (dir-name |
| 1061 | file) | 1042 | (if (string-match "\\.tar\\'" file) |
| 1062 | (error "Invalid package name `%s'" file)) | 1043 | (substring file 0 (match-beginning 0)) |
| 1063 | (let* ((pkg-name (match-string-no-properties 1 file)) | 1044 | (error "Invalid package name `%s'" file))) |
| 1064 | (pkg-version (match-string-no-properties 2 file)) | 1045 | (desc-file (package--description-file dir-name)) |
| 1065 | ;; Extract the package descriptor. | 1046 | ;; Extract the package descriptor. |
| 1066 | (pkg-def-contents (shell-command-to-string | 1047 | (pkg-def-contents (shell-command-to-string |
| 1067 | ;; Requires GNU tar. | 1048 | ;; Requires GNU tar. |
| 1068 | (concat "tar -xOf " file " " | 1049 | (concat "tar -xOf " file " " |
| 1069 | pkg-name "-" pkg-version "/" | 1050 | dir-name "/" desc-file))) |
| 1070 | pkg-name "-pkg.el"))) | 1051 | (pkg-def-parsed (package-read-from-string pkg-def-contents))) |
| 1071 | (pkg-def-parsed (package-read-from-string pkg-def-contents))) | 1052 | (unless (eq (car pkg-def-parsed) 'define-package) |
| 1072 | (unless (eq (car pkg-def-parsed) 'define-package) | 1053 | (error "Can't find define-package in %s" desc-file)) |
| 1073 | (error "No `define-package' sexp is present in `%s-pkg.el'" pkg-name)) | 1054 | (let ((pkg-desc |
| 1074 | (let ((pkg-desc | 1055 | (apply #'package-desc-from-define (append (cdr pkg-def-parsed) |
| 1075 | (apply #'package-desc-from-define (append (cdr pkg-def-parsed) | 1056 | '(:kind tar))))) |
| 1076 | '(:kind tar))))) | 1057 | (unless (equal dir-name (package-desc-full-name pkg-desc)) |
| 1077 | (unless (equal pkg-version | 1058 | ;; FIXME: Shouldn't this just be a message/warning? |
| 1078 | (package-version-join (package-desc-version pkg-desc))) | 1059 | (error "Package has inconsistent name")) |
| 1079 | (error "Package has inconsistent versions")) | 1060 | pkg-desc))) |
| 1080 | (unless (equal pkg-name (symbol-name (package-desc-name pkg-desc))) | ||
| 1081 | (error "Package has inconsistent names")) | ||
| 1082 | pkg-desc)))) | ||
| 1083 | 1061 | ||
| 1084 | 1062 | ||
| 1085 | ;;;###autoload | 1063 | ;;;###autoload |
| @@ -1123,17 +1101,17 @@ The file can either be a tar file or an Emacs Lisp file." | |||
| 1123 | (package-install-from-buffer (package-tar-file-info file))) | 1101 | (package-install-from-buffer (package-tar-file-info file))) |
| 1124 | (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) | 1102 | (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) |
| 1125 | 1103 | ||
| 1126 | (defun package-delete (name version) | 1104 | (defun package-delete (pkg-desc) |
| 1127 | (let ((dir (package--dir name version))) | 1105 | (let ((dir (package-desc-dir pkg-desc))) |
| 1128 | (if (string-equal (file-name-directory dir) | 1106 | (if (string-equal (file-name-directory dir) |
| 1129 | (file-name-as-directory | 1107 | (file-name-as-directory |
| 1130 | (expand-file-name package-user-dir))) | 1108 | (expand-file-name package-user-dir))) |
| 1131 | (progn | 1109 | (progn |
| 1132 | (delete-directory dir t t) | 1110 | (delete-directory dir t t) |
| 1133 | (message "Package `%s-%s' deleted." name version)) | 1111 | (message "Package `%s' deleted." (package-desc-full-name pkg-desc))) |
| 1134 | ;; Don't delete "system" packages | 1112 | ;; Don't delete "system" packages |
| 1135 | (error "Package `%s-%s' is a system package, not deleting" | 1113 | (error "Package `%s' is a system package, not deleting" |
| 1136 | name version)))) | 1114 | (package-desc-full-name pkg-desc))))) |
| 1137 | 1115 | ||
| 1138 | (defun package-archive-base (name) | 1116 | (defun package-archive-base (name) |
| 1139 | "Return the archive containing the package NAME." | 1117 | "Return the archive containing the package NAME." |
| @@ -1212,7 +1190,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." | |||
| 1212 | "Describe package: ") | 1190 | "Describe package: ") |
| 1213 | packages nil t nil nil guess)) | 1191 | packages nil t nil nil guess)) |
| 1214 | (list (if (equal val "") guess (intern val))))) | 1192 | (list (if (equal val "") guess (intern val))))) |
| 1215 | (if (or (null package) (not (symbolp package))) | 1193 | (if (not (and package (symbolp package))) |
| 1216 | (message "No package specified") | 1194 | (message "No package specified") |
| 1217 | (help-setup-xref (list #'describe-package package) | 1195 | (help-setup-xref (list #'describe-package package) |
| 1218 | (called-interactively-p 'interactive)) | 1196 | (called-interactively-p 'interactive)) |
| @@ -1231,7 +1209,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." | |||
| 1231 | ;; Loaded packages are in `package-alist'. | 1209 | ;; Loaded packages are in `package-alist'. |
| 1232 | ((setq desc (cdr (assq package package-alist))) | 1210 | ((setq desc (cdr (assq package package-alist))) |
| 1233 | (setq version (package-version-join (package-desc-version desc))) | 1211 | (setq version (package-version-join (package-desc-version desc))) |
| 1234 | (if (setq pkg-dir (package--dir package-name version)) | 1212 | (if (setq pkg-dir (package-desc-dir desc)) |
| 1235 | (insert "an installed package.\n\n") | 1213 | (insert "an installed package.\n\n") |
| 1236 | ;; This normally does not happen. | 1214 | ;; This normally does not happen. |
| 1237 | (insert "a deleted package.\n\n"))) | 1215 | (insert "a deleted package.\n\n"))) |
| @@ -1279,7 +1257,7 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." | |||
| 1279 | :foreground "black") | 1257 | :foreground "black") |
| 1280 | 'link))) | 1258 | 'link))) |
| 1281 | (insert-text-button button-text 'face button-face 'follow-link t | 1259 | (insert-text-button button-text 'face button-face 'follow-link t |
| 1282 | 'package-symbol package | 1260 | 'package-desc desc |
| 1283 | 'action 'package-install-button-action))) | 1261 | 'action 'package-install-button-action))) |
| 1284 | (built-in | 1262 | (built-in |
| 1285 | (insert (propertize "Built-in." | 1263 | (insert (propertize "Built-in." |
| @@ -1343,9 +1321,10 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." | |||
| 1343 | (goto-char (point-max)))))))) | 1321 | (goto-char (point-max)))))))) |
| 1344 | 1322 | ||
| 1345 | (defun package-install-button-action (button) | 1323 | (defun package-install-button-action (button) |
| 1346 | (let ((package (button-get button 'package-symbol))) | 1324 | (let ((pkg-desc (button-get button 'package-desc))) |
| 1347 | (when (y-or-n-p (format "Install package `%s'? " package)) | 1325 | (when (y-or-n-p (format "Install package `%s'? " |
| 1348 | (package-install package) | 1326 | (package-desc-full-name pkg-desc))) |
| 1327 | (package-install pkg-desc) | ||
| 1349 | (revert-buffer nil t) | 1328 | (revert-buffer nil t) |
| 1350 | (goto-char (point-min))))) | 1329 | (goto-char (point-min))))) |
| 1351 | 1330 | ||
| @@ -1434,29 +1413,26 @@ Letters do not insert themselves; instead, they are commands. | |||
| 1434 | (setq tabulated-list-sort-key (cons "Status" nil)) | 1413 | (setq tabulated-list-sort-key (cons "Status" nil)) |
| 1435 | (tabulated-list-init-header)) | 1414 | (tabulated-list-init-header)) |
| 1436 | 1415 | ||
| 1437 | (defmacro package--push (package desc status listname) | 1416 | (defmacro package--push (pkg-desc status listname) |
| 1438 | "Convenience macro for `package-menu--generate'. | 1417 | "Convenience macro for `package-menu--generate'. |
| 1439 | If the alist stored in the symbol LISTNAME lacks an entry for a | 1418 | If the alist stored in the symbol LISTNAME lacks an entry for a |
| 1440 | package PACKAGE with descriptor DESC, add one. The alist is | 1419 | package PKG-DESC, add one. The alist is keyed with PKG-DESC." |
| 1441 | keyed with cons cells (PACKAGE . VERSION-LIST), where PACKAGE is | 1420 | `(unless (assoc ,pkg-desc ,listname) |
| 1442 | a symbol and VERSION-LIST is a version list." | 1421 | ;; FIXME: Should we move status into pkg-desc? |
| 1443 | `(let* ((version (package-desc-version ,desc)) | 1422 | (push (cons ,pkg-desc ,status) ,listname))) |
| 1444 | (key (cons ,package version))) | ||
| 1445 | (unless (assoc key ,listname) | ||
| 1446 | (push (list key ,status (package-desc-summary ,desc)) ,listname)))) | ||
| 1447 | 1423 | ||
| 1448 | (defun package-menu--generate (remember-pos packages) | 1424 | (defun package-menu--generate (remember-pos packages) |
| 1449 | "Populate the Package Menu. | 1425 | "Populate the Package Menu. |
| 1450 | If REMEMBER-POS is non-nil, keep point on the same entry. | 1426 | If REMEMBER-POS is non-nil, keep point on the same entry. |
| 1451 | PACKAGES should be t, which means to display all known packages, | 1427 | PACKAGES should be t, which means to display all known packages, |
| 1452 | or a list of package names (symbols) to display." | 1428 | or a list of package names (symbols) to display." |
| 1453 | ;; Construct list of ((PACKAGE . VERSION) STATUS DESCRIPTION). | 1429 | ;; Construct list of (PKG-DESC . STATUS). |
| 1454 | (let (info-list name) | 1430 | (let (info-list name) |
| 1455 | ;; Installed packages: | 1431 | ;; Installed packages: |
| 1456 | (dolist (elt package-alist) | 1432 | (dolist (elt package-alist) |
| 1457 | (setq name (car elt)) | 1433 | (setq name (car elt)) |
| 1458 | (when (or (eq packages t) (memq name packages)) | 1434 | (when (or (eq packages t) (memq name packages)) |
| 1459 | (package--push name (cdr elt) | 1435 | (package--push (cdr elt) |
| 1460 | (if (stringp (cadr (assq name package-load-list))) | 1436 | (if (stringp (cadr (assq name package-load-list))) |
| 1461 | "held" "installed") | 1437 | "held" "installed") |
| 1462 | info-list))) | 1438 | info-list))) |
| @@ -1466,14 +1442,14 @@ or a list of package names (symbols) to display." | |||
| 1466 | (setq name (car elt)) | 1442 | (setq name (car elt)) |
| 1467 | (when (and (not (eq name 'emacs)) ; Hide the `emacs' package. | 1443 | (when (and (not (eq name 'emacs)) ; Hide the `emacs' package. |
| 1468 | (or (eq packages t) (memq name packages))) | 1444 | (or (eq packages t) (memq name packages))) |
| 1469 | (package--push name (package--from-builtin elt) "built-in" info-list))) | 1445 | (package--push (package--from-builtin elt) "built-in" info-list))) |
| 1470 | 1446 | ||
| 1471 | ;; Available and disabled packages: | 1447 | ;; Available and disabled packages: |
| 1472 | (dolist (elt package-archive-contents) | 1448 | (dolist (elt package-archive-contents) |
| 1473 | (setq name (car elt)) | 1449 | (setq name (car elt)) |
| 1474 | (when (or (eq packages t) (memq name packages)) | 1450 | (when (or (eq packages t) (memq name packages)) |
| 1475 | (let ((hold (assq name package-load-list))) | 1451 | (let ((hold (assq name package-load-list))) |
| 1476 | (package--push name (cdr elt) | 1452 | (package--push (cdr elt) |
| 1477 | (cond | 1453 | (cond |
| 1478 | ((and hold (null (cadr hold))) "disabled") | 1454 | ((and hold (null (cadr hold))) "disabled") |
| 1479 | ((memq name package-menu--new-package-list) "new") | 1455 | ((memq name package-menu--new-package-list) "new") |
| @@ -1484,7 +1460,7 @@ or a list of package names (symbols) to display." | |||
| 1484 | (dolist (elt package-obsolete-alist) | 1460 | (dolist (elt package-obsolete-alist) |
| 1485 | (dolist (inner-elt (cdr elt)) | 1461 | (dolist (inner-elt (cdr elt)) |
| 1486 | (when (or (eq packages t) (memq (car elt) packages)) | 1462 | (when (or (eq packages t) (memq (car elt) packages)) |
| 1487 | (package--push (car elt) (cdr inner-elt) "obsolete" info-list)))) | 1463 | (package--push (cdr inner-elt) "obsolete" info-list)))) |
| 1488 | 1464 | ||
| 1489 | ;; Print the result. | 1465 | ;; Print the result. |
| 1490 | (setq tabulated-list-entries (mapcar 'package-menu--print-info info-list)) | 1466 | (setq tabulated-list-entries (mapcar 'package-menu--print-info info-list)) |
| @@ -1492,31 +1468,30 @@ or a list of package names (symbols) to display." | |||
| 1492 | 1468 | ||
| 1493 | (defun package-menu--print-info (pkg) | 1469 | (defun package-menu--print-info (pkg) |
| 1494 | "Return a package entry suitable for `tabulated-list-entries'. | 1470 | "Return a package entry suitable for `tabulated-list-entries'. |
| 1495 | PKG has the form ((PACKAGE . VERSION) STATUS DOC). | 1471 | PKG has the form (PKG-DESC . STATUS). |
| 1496 | Return (KEY [NAME VERSION STATUS DOC]), where KEY is the | 1472 | Return (PKG-DESC [NAME VERSION STATUS DOC])." |
| 1497 | identifier (NAME . VERSION-LIST)." | 1473 | (let* ((pkg-desc (car pkg)) |
| 1498 | (let* ((package (caar pkg)) | 1474 | (status (cdr pkg)) |
| 1499 | (version (cdr (car pkg))) | 1475 | (face (pcase status |
| 1500 | (status (nth 1 pkg)) | 1476 | (`"built-in" 'font-lock-builtin-face) |
| 1501 | (doc (or (nth 2 pkg) "")) | 1477 | (`"available" 'default) |
| 1502 | (face (cond | 1478 | (`"new" 'bold) |
| 1503 | ((string= status "built-in") 'font-lock-builtin-face) | 1479 | (`"held" 'font-lock-constant-face) |
| 1504 | ((string= status "available") 'default) | 1480 | (`"disabled" 'font-lock-warning-face) |
| 1505 | ((string= status "new") 'bold) | 1481 | (`"installed" 'font-lock-comment-face) |
| 1506 | ((string= status "held") 'font-lock-constant-face) | 1482 | (_ 'font-lock-warning-face)))) ; obsolete. |
| 1507 | ((string= status "disabled") 'font-lock-warning-face) | 1483 | (list pkg-desc |
| 1508 | ((string= status "installed") 'font-lock-comment-face) | 1484 | (vector (list (symbol-name (package-desc-name pkg-desc)) |
| 1509 | (t 'font-lock-warning-face)))) ; obsolete. | ||
| 1510 | (list (cons package version) | ||
| 1511 | (vector (list (symbol-name package) | ||
| 1512 | 'face 'link | 1485 | 'face 'link |
| 1513 | 'follow-link t | 1486 | 'follow-link t |
| 1514 | 'package-symbol package | 1487 | 'package-desc pkg-desc |
| 1515 | 'action 'package-menu-describe-package) | 1488 | 'action 'package-menu-describe-package) |
| 1516 | (propertize (package-version-join version) | 1489 | (propertize (package-version-join |
| 1490 | (package-desc-version pkg-desc)) | ||
| 1517 | 'font-lock-face face) | 1491 | 'font-lock-face face) |
| 1518 | (propertize status 'font-lock-face face) | 1492 | (propertize status 'font-lock-face face) |
| 1519 | (propertize doc 'font-lock-face face))))) | 1493 | (propertize (package-desc-summary pkg-desc) |
| 1494 | 'font-lock-face face))))) | ||
| 1520 | 1495 | ||
| 1521 | (defun package-menu-refresh () | 1496 | (defun package-menu-refresh () |
| 1522 | "Download the Emacs Lisp package archive. | 1497 | "Download the Emacs Lisp package archive. |
| @@ -1532,10 +1507,11 @@ This fetches the contents of each archive specified in | |||
| 1532 | "Describe the current package. | 1507 | "Describe the current package. |
| 1533 | If optional arg BUTTON is non-nil, describe its associated package." | 1508 | If optional arg BUTTON is non-nil, describe its associated package." |
| 1534 | (interactive) | 1509 | (interactive) |
| 1535 | (let ((package (if button (button-get button 'package-symbol) | 1510 | (let ((pkg-desc (if button (button-get button 'package-desc) |
| 1536 | (car (tabulated-list-get-id))))) | 1511 | (car (tabulated-list-get-id))))) |
| 1537 | (if package | 1512 | (if pkg-desc |
| 1538 | (describe-package package)))) | 1513 | ;; FIXME: We could actually describe this particular pkg-desc. |
| 1514 | (describe-package (package-desc-name pkg-desc))))) | ||
| 1539 | 1515 | ||
| 1540 | ;; fixme numeric argument | 1516 | ;; fixme numeric argument |
| 1541 | (defun package-menu-mark-delete (&optional _num) | 1517 | (defun package-menu-mark-delete (&optional _num) |
| @@ -1582,8 +1558,8 @@ If optional arg BUTTON is non-nil, describe its associated package." | |||
| 1582 | 'package-menu-view-commentary 'package-menu-describe-package "24.1") | 1558 | 'package-menu-view-commentary 'package-menu-describe-package "24.1") |
| 1583 | 1559 | ||
| 1584 | (defun package-menu-get-status () | 1560 | (defun package-menu-get-status () |
| 1585 | (let* ((pkg (tabulated-list-get-id)) | 1561 | (let* ((id (tabulated-list-get-id)) |
| 1586 | (entry (and pkg (assq pkg tabulated-list-entries)))) | 1562 | (entry (and id (assq id tabulated-list-entries)))) |
| 1587 | (if entry | 1563 | (if entry |
| 1588 | (aref (cadr entry) 2) | 1564 | (aref (cadr entry) 2) |
| 1589 | ""))) | 1565 | ""))) |
| @@ -1592,18 +1568,20 @@ If optional arg BUTTON is non-nil, describe its associated package." | |||
| 1592 | (let (installed available upgrades) | 1568 | (let (installed available upgrades) |
| 1593 | ;; Build list of installed/available packages in this buffer. | 1569 | ;; Build list of installed/available packages in this buffer. |
| 1594 | (dolist (entry tabulated-list-entries) | 1570 | (dolist (entry tabulated-list-entries) |
| 1595 | ;; ENTRY is ((NAME . VERSION) [NAME VERSION STATUS DOC]) | 1571 | ;; ENTRY is (PKG-DESC [NAME VERSION STATUS DOC]) |
| 1596 | (let ((pkg (car entry)) | 1572 | (let ((pkg-desc (car entry)) |
| 1597 | (status (aref (cadr entry) 2))) | 1573 | (status (aref (cadr entry) 2))) |
| 1598 | (cond ((equal status "installed") | 1574 | (cond ((equal status "installed") |
| 1599 | (push pkg installed)) | 1575 | (push pkg-desc installed)) |
| 1600 | ((member status '("available" "new")) | 1576 | ((member status '("available" "new")) |
| 1601 | (push pkg available))))) | 1577 | (push (cons (package-desc-name pkg-desc) pkg-desc) |
| 1602 | ;; Loop through list of installed packages, finding upgrades | 1578 | available))))) |
| 1603 | (dolist (pkg installed) | 1579 | ;; Loop through list of installed packages, finding upgrades. |
| 1604 | (let ((avail-pkg (assq (car pkg) available))) | 1580 | (dolist (pkg-desc installed) |
| 1581 | (let ((avail-pkg (assq (package-desc-name pkg-desc) available))) | ||
| 1605 | (and avail-pkg | 1582 | (and avail-pkg |
| 1606 | (version-list-< (cdr pkg) (cdr avail-pkg)) | 1583 | (version-list-< (package-desc-version pkg-desc) |
| 1584 | (package-desc-version (cdr avail-pkg))) | ||
| 1607 | (push avail-pkg upgrades)))) | 1585 | (push avail-pkg upgrades)))) |
| 1608 | upgrades)) | 1586 | upgrades)) |
| 1609 | 1587 | ||
| @@ -1623,11 +1601,11 @@ call will upgrade the package." | |||
| 1623 | (save-excursion | 1601 | (save-excursion |
| 1624 | (goto-char (point-min)) | 1602 | (goto-char (point-min)) |
| 1625 | (while (not (eobp)) | 1603 | (while (not (eobp)) |
| 1626 | (let* ((pkg (tabulated-list-get-id)) | 1604 | (let* ((pkg-desc (tabulated-list-get-id)) |
| 1627 | (upgrade (assq (car pkg) upgrades))) | 1605 | (upgrade (cdr (assq (package-desc-name pkg-desc) upgrades)))) |
| 1628 | (cond ((null upgrade) | 1606 | (cond ((null upgrade) |
| 1629 | (forward-line 1)) | 1607 | (forward-line 1)) |
| 1630 | ((equal pkg upgrade) | 1608 | ((equal pkg-desc upgrade) |
| 1631 | (package-menu-mark-install)) | 1609 | (package-menu-mark-install)) |
| 1632 | (t | 1610 | (t |
| 1633 | (package-menu-mark-delete)))))) | 1611 | (package-menu-mark-delete)))))) |
| @@ -1643,30 +1621,30 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." | |||
| 1643 | (interactive) | 1621 | (interactive) |
| 1644 | (unless (derived-mode-p 'package-menu-mode) | 1622 | (unless (derived-mode-p 'package-menu-mode) |
| 1645 | (error "The current buffer is not in Package Menu mode")) | 1623 | (error "The current buffer is not in Package Menu mode")) |
| 1646 | (let (install-list delete-list cmd id) | 1624 | (let (install-list delete-list cmd pkg-desc) |
| 1647 | (save-excursion | 1625 | (save-excursion |
| 1648 | (goto-char (point-min)) | 1626 | (goto-char (point-min)) |
| 1649 | (while (not (eobp)) | 1627 | (while (not (eobp)) |
| 1650 | (setq cmd (char-after)) | 1628 | (setq cmd (char-after)) |
| 1651 | (unless (eq cmd ?\s) | 1629 | (unless (eq cmd ?\s) |
| 1652 | ;; This is the key (PACKAGE . VERSION-LIST). | 1630 | ;; This is the key PKG-DESC. |
| 1653 | (setq id (tabulated-list-get-id)) | 1631 | (setq pkg-desc (tabulated-list-get-id)) |
| 1654 | (cond ((eq cmd ?D) | 1632 | (cond ((eq cmd ?D) |
| 1655 | (push (cons (symbol-name (car id)) | 1633 | (push pkg-desc delete-list)) |
| 1656 | (package-version-join (cdr id))) | ||
| 1657 | delete-list)) | ||
| 1658 | ((eq cmd ?I) | 1634 | ((eq cmd ?I) |
| 1659 | (push (car id) install-list)))) | 1635 | (push pkg-desc install-list)))) |
| 1660 | (forward-line))) | 1636 | (forward-line))) |
| 1661 | (when install-list | 1637 | (when install-list |
| 1662 | (if (or | 1638 | (if (or |
| 1663 | noquery | 1639 | noquery |
| 1664 | (yes-or-no-p | 1640 | (yes-or-no-p |
| 1665 | (if (= (length install-list) 1) | 1641 | (if (= (length install-list) 1) |
| 1666 | (format "Install package `%s'? " (car install-list)) | 1642 | (format "Install package `%s'? " |
| 1667 | (format "Install these %d packages (%s)? " | 1643 | (package-desc-full-name (car install-list))) |
| 1668 | (length install-list) | 1644 | (format "Install these %d packages (%s)? " |
| 1669 | (mapconcat 'symbol-name install-list ", "))))) | 1645 | (length install-list) |
| 1646 | (mapconcat #'package-desc-full-name | ||
| 1647 | install-list ", "))))) | ||
| 1670 | (mapc 'package-install install-list))) | 1648 | (mapc 'package-install install-list))) |
| 1671 | ;; Delete packages, prompting if necessary. | 1649 | ;; Delete packages, prompting if necessary. |
| 1672 | (when delete-list | 1650 | (when delete-list |
| @@ -1674,18 +1652,15 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." | |||
| 1674 | noquery | 1652 | noquery |
| 1675 | (yes-or-no-p | 1653 | (yes-or-no-p |
| 1676 | (if (= (length delete-list) 1) | 1654 | (if (= (length delete-list) 1) |
| 1677 | (format "Delete package `%s-%s'? " | 1655 | (format "Delete package `%s'? " |
| 1678 | (caar delete-list) | 1656 | (package-desc-full-name (car delete-list))) |
| 1679 | (cdr (car delete-list))) | ||
| 1680 | (format "Delete these %d packages (%s)? " | 1657 | (format "Delete these %d packages (%s)? " |
| 1681 | (length delete-list) | 1658 | (length delete-list) |
| 1682 | (mapconcat (lambda (elt) | 1659 | (mapconcat #'package-desc-full-name |
| 1683 | (concat (car elt) "-" (cdr elt))) | 1660 | delete-list ", "))))) |
| 1684 | delete-list | ||
| 1685 | ", "))))) | ||
| 1686 | (dolist (elt delete-list) | 1661 | (dolist (elt delete-list) |
| 1687 | (condition-case-unless-debug err | 1662 | (condition-case-unless-debug err |
| 1688 | (package-delete (car elt) (cdr elt)) | 1663 | (package-delete elt) |
| 1689 | (error (message (cadr err))))) | 1664 | (error (message (cadr err))))) |
| 1690 | (error "Aborted"))) | 1665 | (error "Aborted"))) |
| 1691 | ;; If we deleted anything, regenerate `package-alist'. This is done | 1666 | ;; If we deleted anything, regenerate `package-alist'. This is done |
| @@ -1730,8 +1705,8 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." | |||
| 1730 | (string< dA dB)))) | 1705 | (string< dA dB)))) |
| 1731 | 1706 | ||
| 1732 | (defun package-menu--name-predicate (A B) | 1707 | (defun package-menu--name-predicate (A B) |
| 1733 | (string< (symbol-name (caar A)) | 1708 | (string< (symbol-name (package-desc-name (car A))) |
| 1734 | (symbol-name (caar B)))) | 1709 | (symbol-name (package-desc-name (car B))))) |
| 1735 | 1710 | ||
| 1736 | ;;;###autoload | 1711 | ;;;###autoload |
| 1737 | (defun list-packages (&optional no-fetch) | 1712 | (defun list-packages (&optional no-fetch) |
diff --git a/lisp/startup.el b/lisp/startup.el index f21e8c4aa11..bd1e0db03e6 100644 --- a/lisp/startup.el +++ b/lisp/startup.el | |||
| @@ -422,6 +422,13 @@ The second subexpression is the version string. | |||
| 422 | The regexp should not contain a starting \"\\`\" or a trailing | 422 | The regexp should not contain a starting \"\\`\" or a trailing |
| 423 | \"\\'\"; those are added automatically by callers.") | 423 | \"\\'\"; those are added automatically by callers.") |
| 424 | 424 | ||
| 425 | (defun package--description-file (dir) | ||
| 426 | (concat (let ((subdir (file-name-nondirectory | ||
| 427 | (directory-file-name dir)))) | ||
| 428 | (if (string-match package-subdirectory-regexp subdir) | ||
| 429 | (match-string 1 subdir) subdir)) | ||
| 430 | "-pkg.el")) | ||
| 431 | |||
| 425 | (defun normal-top-level-add-subdirs-to-load-path () | 432 | (defun normal-top-level-add-subdirs-to-load-path () |
| 426 | "Add all subdirectories of `default-directory' to `load-path'. | 433 | "Add all subdirectories of `default-directory' to `load-path'. |
| 427 | More precisely, this uses only the subdirectories whose names | 434 | More precisely, this uses only the subdirectories whose names |
| @@ -1194,10 +1201,10 @@ the `--debug-init' option to view a complete error backtrace." | |||
| 1194 | (dolist (dir dirs) | 1201 | (dolist (dir dirs) |
| 1195 | (when (file-directory-p dir) | 1202 | (when (file-directory-p dir) |
| 1196 | (dolist (subdir (directory-files dir)) | 1203 | (dolist (subdir (directory-files dir)) |
| 1197 | (when (and (file-directory-p (expand-file-name subdir dir)) | 1204 | (when (let ((subdir (expand-file-name subdir dir))) |
| 1198 | (string-match | 1205 | (and (file-directory-p subdir) |
| 1199 | (concat "\\`" package-subdirectory-regexp "\\'") | 1206 | (file-exists-p |
| 1200 | subdir)) | 1207 | (package--description-file subdir)))) |
| 1201 | (throw 'package-dir-found t))))))) | 1208 | (throw 'package-dir-found t))))))) |
| 1202 | (package-initialize)) | 1209 | (package-initialize)) |
| 1203 | 1210 | ||