diff options
author | Jan D <jan.h.d@swipnet.se> | 2015-05-17 16:46:34 +0200 |
---|---|---|
committer | Jan D <jan.h.d@swipnet.se> | 2015-05-17 16:46:34 +0200 |
commit | 6445ee0fb751ae2c1dfef900d44721b3d952812f (patch) | |
tree | d43006cb93d9ea7b00ea02aabcd5577c41ff827f /lisp/emacs-lisp/package.el | |
parent | f92ac2e82ed199d6f25d2a59508e08addb1150ac (diff) | |
parent | c9c4708ed47b18987940a71b98eb9873150d2b95 (diff) | |
download | emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.tar.gz emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.tar.bz2 emacs-6445ee0fb751ae2c1dfef900d44721b3d952812f.zip |
Merge branch 'master' into cairo
Diffstat (limited to 'lisp/emacs-lisp/package.el')
-rw-r--r-- | lisp/emacs-lisp/package.el | 274 |
1 files changed, 150 insertions, 124 deletions
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index f770acd557e..55fa962719d 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -185,7 +185,6 @@ and before `after-init-hook'. Activation is not done if Even if the value is nil, you can type \\[package-initialize] to activate the package system at any time." :type 'boolean - :group 'package :version "24.1") (defcustom package-load-list '(all) @@ -203,7 +202,6 @@ If VERSION is a string, only that version is ever loaded. If VERSION is nil, the package is not loaded (it is \"disabled\")." :type '(repeat symbol) :risky t - :group 'package :version "24.1") (defcustom package-archives '(("gnu" . "http://elpa.gnu.org/packages/")) @@ -222,7 +220,6 @@ a package can run arbitrary code." :type '(alist :key-type (string :tag "Archive name") :value-type (string :tag "URL or directory name")) :risky t - :group 'package :version "24.1") (defcustom package-menu-hide-low-priority 'archive @@ -246,7 +243,6 @@ nil, so it can be toggled with \\<package-menu-mode-map> \\[package-menu-hide-ob (const :tag "Hide per package-archive-priorities" archive) (const :tag "Hide per archive and version number" t)) - :group 'package :version "25.1") (defcustom package-archive-priorities nil @@ -265,7 +261,6 @@ See also `package-menu-hide-low-priority'." :type '(alist :key-type (string :tag "Archive name") :value-type (integer :tag "Priority (default is 0)")) :risky t - :group 'package :version "25.1") (defcustom package-pinned-packages nil @@ -289,7 +284,6 @@ the package will be unavailable." ;; via an entry (PACKAGE . NON-EXISTING). Which could be an issue ;; if PACKAGE has a known vulnerability that is fixed in newer versions. :risky t - :group 'package :version "24.4") (defcustom package-user-dir (locate-user-emacs-file "elpa") @@ -299,7 +293,6 @@ Apart from this directory, Emacs also looks for system-wide packages in `package-directory-list'." :type 'directory :risky t - :group 'package :version "24.1") (defcustom package-directory-list @@ -317,7 +310,6 @@ These directories contain packages intended for system-wide; in contrast, `package-user-dir' contains packages for personal use." :type '(repeat directory) :risky t - :group 'package :version "24.1") (defvar epg-gpg-program) @@ -335,14 +327,12 @@ contents of the archive." (const allow-unsigned :tag "Allow unsigned") (const t :tag "Check always")) :risky t - :group 'package :version "24.4") (defcustom package-unsigned-archives nil "List of archives where we do not check for package signatures." :type '(repeat (string :tag "Archive name")) :risky t - :group 'package :version "24.4") (defcustom package-selected-packages nil @@ -356,9 +346,15 @@ by running `package-user-selected-packages-install'. To check if a package is contained in this list here, use `package--user-selected-p', as it may populate the variable with a sane initial value." - :group 'package :type '(repeat symbol)) +(defcustom package-menu-async t + "If non-nil, package-menu will use async operations when possible. +This includes refreshing archive contents as well as installing +packages." + :type 'boolean + :version "25.1") + ;;; `package-desc' object definition ;; This is the struct used internally to represent packages. @@ -897,7 +893,7 @@ untar into a directory named DIR; otherwise, signal an error." ;;(ignore-name (concat name "-pkg.el")) (generated-autoload-file (expand-file-name auto-name pkg-dir)) ;; Silence `autoload-generate-file-autoloads'. - (noninteractive package--silence) + (noninteractive inhibit-message) (backup-inhibited t) (version-control 'never)) (package-autoload-ensure-default-file generated-autoload-file) @@ -917,10 +913,13 @@ untar into a directory named DIR; otherwise, signal an error." ) ;;;; Compilation +(defvar warning-minimum-level) (defun package--compile (pkg-desc) "Byte-compile installed package PKG-DESC." - (package-activate-1 pkg-desc) - (byte-recompile-directory (package-desc-dir pkg-desc) 0 t)) + (let ((warning-minimum-level :error) + (save-silently inhibit-message)) + (package-activate-1 pkg-desc) + (byte-recompile-directory (package-desc-dir pkg-desc) 0 t))) ;;;; Inferring package from current buffer (defun package-read-from-string (str) @@ -958,7 +957,7 @@ is wrapped around any parts requiring it." deps)))) (declare-function lm-header "lisp-mnt" (header)) -(declare-function lm-homepage "lisp-mnt" ()) +(declare-function lm-homepage "lisp-mnt" (&optional file)) (defun package-buffer-info () "Return a `package-desc' describing the package in the current buffer. @@ -1080,7 +1079,7 @@ The return result is a `package-desc'." (declare-function epg-verify-string "epg" (context signature &optional signed-text)) (declare-function epg-context-result-for "epg" (context name)) -(declare-function epg-signature-status "epg" (signature)) +(declare-function epg-signature-status "epg" (signature) t) (declare-function epg-signature-to-string "epg" (signature)) (defun package--display-verify-error (context sig-file) @@ -1137,7 +1136,8 @@ arguments see `package--with-work-buffer'." (signal (cdar status) (cddr status))) (goto-char (point-min)) (unless (search-forward "\n\n" nil 'noerror) - (error "Invalid url response")) + (error "Invalid url response in buffer %s" + (current-buffer))) (delete-region (point-min) (point)) ,@body) (kill-buffer (current-buffer))) @@ -1346,6 +1346,9 @@ If successful, set `package-archive-contents'." ;; available on disk. (defvar package--initialized nil) +(defvar package--init-file-ensured nil + "Whether we know the init file has package-initialize.") + ;;;###autoload (defun package-initialize (&optional no-activate) "Load Emacs Lisp packages, and activate them. @@ -1355,7 +1358,11 @@ If `user-init-file' does not mention `(package-initialize)', add it to the file." (interactive) (setq package-alist nil) - (package--ensure-init-file) + (if (equal user-init-file load-file-name) + ;; If `package-initialize' is being called as part of loading + ;; the init file, it's obvious we don't need to ensure-init. + (setq package--init-file-ensured t) + (package--ensure-init-file)) (package-load-all-descriptors) (package-read-all-archive-contents) (unless no-activate @@ -1378,16 +1385,6 @@ it to the file." (declare-function epg-configuration "epg-config" ()) (declare-function epg-import-keys-from-file "epg" (context keys)) -(defvar package--silence nil) - -(defun package--message (format &rest args) - "Like `message', except sometimes don't print to minibuffer. -If the variable `package--silence' is non-nil, the message is not -displayed on the minibuffer." - (apply #'message format args) - (when package--silence - (message nil))) - ;;;###autoload (defun package-import-keyring (&optional file) "Import keys from FILE." @@ -1398,9 +1395,9 @@ displayed on the minibuffer." (with-file-modes 448 (make-directory homedir t)) (setf (epg-context-home-directory context) homedir) - (package--message "Importing %s..." (file-name-nondirectory file)) + (message "Importing %s..." (file-name-nondirectory file)) (epg-import-keys-from-file context file) - (package--message "Importing %s...done" (file-name-nondirectory file)))) + (message "Importing %s...done" (file-name-nondirectory file)))) (defvar package--post-download-archives-hook nil "Hook run after the archive contents are downloaded. @@ -1466,9 +1463,9 @@ This populates `package-archive-contents'. If ASYNC is non-nil, perform the downloads asynchronously." ;; The downloaded archive contents will be read as part of ;; `package--update-downloads-in-progress'. - (setq package--downloads-in-progress - (append package-archives - package--downloads-in-progress)) + (dolist (archive package-archives) + (cl-pushnew archive package--downloads-in-progress + :test #'equal)) (dolist (archive package-archives) (condition-case-unless-debug nil (package--download-one-archive @@ -1492,14 +1489,14 @@ downloads in the background." (make-directory package-user-dir t)) (let ((default-keyring (expand-file-name "package-keyring.gpg" data-directory)) - (package--silence async)) + (inhibit-message async)) (when (and package-check-signature (file-exists-p default-keyring)) (condition-case-unless-debug error (progn (epg-check-configuration (epg-configuration)) (package-import-keyring default-keyring)) - (error (message "Cannot import default keyring: %S" (cdr error))))) - (package--download-and-read-archives async))) + (error (message "Cannot import default keyring: %S" (cdr error)))))) + (package--download-and-read-archives async)) ;;; Dependency Management @@ -1541,7 +1538,7 @@ SEEN is used internally to detect infinite recursion." ;; we re-add it (along with its dependencies) at an earlier place ;; below (bug#16994). (if (memq already seen) ;Avoid inf-loop on dependency cycles. - (package--message "Dependency cycle going through %S" + (message "Dependency cycle going through %S" (package-desc-full-name already)) (setq packages (delq already packages)) (setq already nil)) @@ -1607,7 +1604,7 @@ Used to populate `package-selected-packages'." (defun package--save-selected-packages (value) "Set and save `package-selected-packages' to VALUE." - (let ((save-silently package--silence)) + (let ((save-silently inhibit-message)) (customize-save-variable 'package-selected-packages (setq package-selected-packages value)))) @@ -1728,7 +1725,8 @@ operation is done." package-unsigned-archives)) ;; If we don't care about the signature, unpack and we're ;; done. - (progn (let ((save-silently async)) + (progn (let ((save-silently async) + (inhibit-message async)) (package-unpack pkg-desc)) (funcall callback)) ;; If we care, check it and *then* write the file. @@ -1744,7 +1742,8 @@ operation is done." (package-desc-name pkg-desc))) ;; Signature checked, unpack now. (with-temp-buffer (insert content) - (let ((save-silently async)) + (let ((save-silently async) + (inhibit-message async)) (package-unpack pkg-desc))) ;; Here the package has been installed successfully, mark it as ;; signed if appropriate. @@ -1804,9 +1803,15 @@ using `package-compute-transaction'." (callback (funcall callback)))) (defun package--ensure-init-file () - "Ensure that the user's init file calls `package-initialize'." + "Ensure that the user's init file has `package-initialize'. +`package-initialize' doesn't have to be called, as long as it is +present somewhere in the file, even as a comment. If it is not, +add a call to it along with some explanatory comments." ;; Don't mess with the init-file from "emacs -Q". - (when user-init-file + (when (and (stringp user-init-file) + (not package--init-file-ensured) + (file-readable-p user-init-file) + (file-writable-p user-init-file)) (let* ((buffer (find-buffer-visiting user-init-file)) (contains-init (if buffer @@ -1816,6 +1821,7 @@ using `package-compute-transaction'." (widen) (goto-char (point-min)) (search-forward "(package-initialize)" nil 'noerror)))) + ;; Don't visit the file if we don't have to. (with-temp-buffer (insert-file-contents user-init-file) (goto-char (point-min)) @@ -1828,7 +1834,11 @@ using `package-compute-transaction'." (save-restriction (widen) (goto-char (point-min)) + (while (and (looking-at-p "[[:blank:]]*\\(;\\|$\\)") + (not (eobp))) + (forward-line 1)) (insert + "\n" ";; Added by Package.el. This must come before configurations of\n" ";; installed packages. Don't delete this line. If you don't want it,\n" ";; just comment it out by adding a semicolon to the start of the line.\n" @@ -1839,7 +1849,8 @@ using `package-compute-transaction'." (let ((file-precious-flag t)) (save-buffer)) (unless buffer - (kill-buffer (current-buffer)))))))))) + (kill-buffer (current-buffer))))))))) + (setq package--init-file-ensured t)) ;;;###autoload (defun package-install (pkg &optional dont-select async callback) @@ -1885,7 +1896,8 @@ to install it but still mark it as selected." (package-desc-reqs pkg))) (package-compute-transaction () (list (list pkg)))))) (package-download-transaction transaction async callback) - (package--message "`%s' is already installed" (package-desc-full-name pkg)))) + (message "`%s' is already installed" (package-desc-full-name pkg)) + (funcall callback))) (defun package-strip-rcs-id (str) "Strip RCS version ID from the version string STR. @@ -1953,7 +1965,7 @@ The file can either be a tar file or an Emacs Lisp file." (package-install-from-buffer))) ;;;###autoload -(defun package-install-user-selected-packages () +(defun package-install-selected-packages () "Ensure packages in `package-selected-packages' are installed. If some packages are not installed propose to install them." (interactive) @@ -2027,7 +2039,7 @@ If NOSAVE is non-nil, the package is not removed from (delete pkg-desc pkgs) (unless (cdr pkgs) (setq package-alist (delq pkgs package-alist)))) - (package--message "Package `%s' deleted." (package-desc-full-name pkg-desc)))))) + (message "Package `%s' deleted." (package-desc-full-name pkg-desc)))))) ;;;###autoload (defun package-reinstall (pkg) @@ -2457,16 +2469,17 @@ of these dependencies, similar to the list returned by ((version-list-= version hv) "held") ((version-list-< version hv) "obsolete") (t "disabled")))) - ((package-built-in-p name version) "obsolete") - ((package--incompatible-p pkg-desc) "incompat") (dir ;One of the installed packages. (cond - ((not (file-exists-p (package-desc-dir pkg-desc))) "deleted") + ((not (file-exists-p dir)) "deleted") + ;; Not inside `package-user-dir'. + ((not (file-in-directory-p dir package-user-dir)) "external") ((eq pkg-desc (cadr (assq name package-alist))) (if (not signed) "unsigned" (if (package--user-selected-p name) "installed" "dependency"))) (t "obsolete"))) + ((package--incompatible-p pkg-desc) "incompat") (t (let* ((ins (cadr (assq name package-alist))) (ins-v (if ins (package-desc-version ins)))) @@ -2497,29 +2510,43 @@ Installed obsolete packages are always displayed.") (defun package--remove-hidden (pkg-list) "Filter PKG-LIST according to `package-archive-priorities'. -PKG-LIST must be a list of package-desc objects sorted by -decreasing version number. +PKG-LIST must be a list of package-desc objects, all with the +same name, sorted by decreasing `package-desc-priority-version'. Return a list of packages tied for the highest priority according to their archives." (when pkg-list - ;; The first is a variable toggled with - ;; `package-menu-hide-obsolete', the second is a static user - ;; option that defines *what* we hide. - (if (and package-menu--hide-obsolete - package-menu-hide-low-priority) - (let ((max-priority (package-desc-priority (car pkg-list))) - (out (list (pop pkg-list)))) - (dolist (p pkg-list (nreverse out)) - (let ((priority (package-desc-priority p))) - (cond - ((> priority max-priority) - (setq max-priority priority) - (setq out (list p))) - ;; This assumes pkg-list is sorted by version number. - ((and (= priority max-priority) - (eq package-menu-hide-low-priority 'archive)) - (push p out)))))) - pkg-list))) + ;; Variable toggled with `package-menu-hide-obsolete'. + (if (not package-menu--hide-obsolete) + pkg-list + (let ((installed (cadr (assq (package-desc-name (car pkg-list)) + package-alist)))) + (when installed + (setq pkg-list + (let ((ins-version (package-desc-version installed))) + (cl-remove-if (lambda (p) (version-list-< (package-desc-version p) + ins-version)) + pkg-list)))) + (let ((filtered-by-priority + (cond + ((not package-menu-hide-low-priority) + pkg-list) + ((eq package-menu-hide-low-priority 'archive) + (let* ((max-priority most-negative-fixnum) + (out)) + (while pkg-list + (let ((p (pop pkg-list))) + (if (>= (package-desc-priority p) max-priority) + (push p out) + (setq pkg-list nil)))) + (nreverse out))) + (pkg-list + (list (car pkg-list)))))) + (if (not installed) + filtered-by-priority + (let ((ins-version (package-desc-version installed))) + (cl-remove-if (lambda (p) (version-list-= (package-desc-version p) + ins-version)) + filtered-by-priority)))))))) (defun package-menu--refresh (&optional packages keywords) "Re-populate the `tabulated-list-entries'. @@ -2527,40 +2554,38 @@ PACKAGES should be nil or t, which means to display all known packages. KEYWORDS should be nil or a list of keywords." ;; Construct list of (PKG-DESC . STATUS). (unless packages (setq packages t)) - (let (info-list name) + (let (info-list) ;; Installed packages: (dolist (elt package-alist) - (setq name (car elt)) - (when (or (eq packages t) (memq name packages)) - (dolist (pkg (cdr elt)) - (when (package--has-keyword-p pkg keywords) - (package--push pkg (package-desc-status pkg) info-list))))) + (let ((name (car elt))) + (when (or (eq packages t) (memq name packages)) + (dolist (pkg (cdr elt)) + (when (package--has-keyword-p pkg keywords) + (push pkg info-list)))))) ;; Built-in packages: (dolist (elt package--builtins) - (setq name (car elt)) - (when (and (not (eq name 'emacs)) ; Hide the `emacs' package. - (package--has-keyword-p (package--from-builtin elt) keywords) - (or package-list-unversioned - (package--bi-desc-version (cdr elt))) - (or (eq packages t) (memq name packages))) - (package--push (package--from-builtin elt) "built-in" info-list))) + (let ((pkg (package--from-builtin elt)) + (name (car elt))) + (when (not (eq name 'emacs)) ; Hide the `emacs' package. + (when (and (package--has-keyword-p pkg keywords) + (or package-list-unversioned + (package--bi-desc-version (cdr elt))) + (or (eq packages t) (memq name packages))) + (push pkg info-list))))) ;; Available and disabled packages: (dolist (elt package-archive-contents) - (setq name (car elt)) - (when (or (eq packages t) (memq name packages)) - (dolist (pkg (package--remove-hidden (cdr elt))) - ;; Hide available obsolete packages. - (when (and (not (and package-menu--hide-obsolete - (package-installed-p (package-desc-name pkg) - (package-desc-version pkg)))) - (package--has-keyword-p pkg keywords)) - (package--push pkg (package-desc-status pkg) info-list))))) + (let ((name (car elt))) + (when (or (eq packages t) (memq name packages)) + ;; Hide available-obsolete or low-priority packages. + (dolist (pkg (package--remove-hidden (cdr elt))) + (when (package--has-keyword-p pkg keywords) + (push pkg info-list)))))) ;; Print the result. (setq tabulated-list-entries - (mapcar #'package-menu--print-info info-list)))) + (mapcar #'package-menu--print-info-simple info-list)))) (defun package-all-keywords () "Collect all package keywords" @@ -2642,10 +2667,18 @@ shown." "Return a package entry suitable for `tabulated-list-entries'. PKG has the form (PKG-DESC . STATUS). Return (PKG-DESC [NAME VERSION STATUS DOC])." - (let* ((pkg-desc (car pkg)) - (status (cdr pkg)) + (package-menu--print-info-simple (car pkg))) +(make-obsolete 'package-menu--print-info + 'package-menu--print-info-simple "25.1") + +(defun package-menu--print-info-simple (pkg) + "Return a package entry suitable for `tabulated-list-entries'. +PKG is a package-desc object. +Return (PKG-DESC [NAME VERSION STATUS DOC])." + (let* ((status (package-desc-status pkg)) (face (pcase status (`"built-in" 'font-lock-builtin-face) + (`"external" 'font-lock-builtin-face) (`"available" 'default) (`"avail-obso" 'font-lock-comment-face) (`"new" 'bold) @@ -2656,21 +2689,23 @@ Return (PKG-DESC [NAME VERSION STATUS DOC])." (`"unsigned" 'font-lock-warning-face) (`"incompat" 'font-lock-comment-face) (_ 'font-lock-warning-face)))) ; obsolete. - (list pkg-desc - `[,(list (symbol-name (package-desc-name pkg-desc)) - 'face 'link - 'follow-link t - 'package-desc pkg-desc - 'action 'package-menu-describe-package) + (list pkg + `[(,(symbol-name (package-desc-name pkg)) + face link + follow-link t + package-desc ,pkg + action package-menu-describe-package) ,(propertize (package-version-join - (package-desc-version pkg-desc)) + (package-desc-version pkg)) 'font-lock-face face) ,(propertize status 'font-lock-face face) ,@(if (cdr package-archives) - (list (propertize (or (package-desc-archive pkg-desc) "") + (list (propertize (or (package-desc-archive pkg) "") 'font-lock-face face))) - ,(propertize (package-desc-summary pkg-desc) - 'font-lock-face face)]))) + ,(package-desc-summary pkg)]))) + +(defvar package-menu--old-archive-contents nil + "`package-archive-contents' before the latest refresh.") (defun package-menu-refresh () "Download the Emacs Lisp package archive. @@ -2887,19 +2922,19 @@ asynchronously." (package-install pkg dont-mark async (lambda () (package-menu--perform-transaction rest delete-list async)))) - ;; Once there are no more packages to install, proceed to - ;; deletion. - (let ((package--silence async)) + (let ((inhibit-message async)) + ;; Once there are no more packages to install, proceed to + ;; deletion. (dolist (elt (package--sort-by-dependence delete-list)) (condition-case-unless-debug err (package-delete elt) - (error (message (cadr err))))) - (when package-selected-packages - (when-let ((removable (package--removable-packages))) - (package--message "These %d packages are no longer needed, type `M-x package-autoremove' to remove them (%s)" - (length removable) - (mapconcat #'symbol-name removable ", "))))) + (error (message (cadr err)))))) (message "Transaction done") + (when package-selected-packages + (when-let ((removable (package--removable-packages))) + (message "These %d packages are no longer needed, type `M-x package-autoremove' to remove them (%s)" + (length removable) + (mapconcat #'symbol-name removable ", ")))) (package-menu--post-refresh))) (defun package-menu-execute (&optional noquery) @@ -2959,6 +2994,8 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." ((string= sB "unsigned") nil) ((string= sA "held") t) ((string= sB "held") nil) + ((string= sA "external") t) + ((string= sB "external") nil) ((string= sA "built-in") t) ((string= sB "built-in") nil) ((string= sA "obsolete") t) @@ -2982,9 +3019,6 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." (string< (or (package-desc-archive (car A)) "") (or (package-desc-archive (car B)) ""))) -(defvar package-menu--old-archive-contents nil - "`package-archive-contents' before the latest refresh.") - (defun package-menu--populate-new-package-list () "Decide which packages are new in `package-archives-contents'. Store this list in `package-menu--new-package-list'." @@ -3015,14 +3049,6 @@ after `package-menu--perform-transaction'." (revert-buffer nil 'noconfirm)))) (package-menu--find-and-notify-upgrades)) -(defcustom package-menu-async t - "If non-nil, package-menu will use async operations when possible. -This includes refreshing archive contents as well as installing -packages." - :type 'boolean - :version "25.1" - :group 'package) - ;;;###autoload (defun list-packages (&optional no-fetch) "Display a list of packages. |