summaryrefslogtreecommitdiff
path: root/lisp/use-package/use-package-core.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/use-package/use-package-core.el')
-rw-r--r--lisp/use-package/use-package-core.el145
1 files changed, 132 insertions, 13 deletions
diff --git a/lisp/use-package/use-package-core.el b/lisp/use-package/use-package-core.el
index 3eef056b137..d9343e14839 100644
--- a/lisp/use-package/use-package-core.el
+++ b/lisp/use-package/use-package-core.el
@@ -4,7 +4,6 @@
;; Author: John Wiegley <johnw@newartisans.com>
;; Maintainer: John Wiegley <johnw@newartisans.com>
-;; Package: use-package
;; This file is part of GNU Emacs.
@@ -77,6 +76,7 @@
:functions
:preface
:if :when :unless
+ :vc
:no-require
:catch
:after
@@ -327,12 +327,15 @@ Must be set before loading `use-package'."
(set-default sym value))
:group 'use-package)
+;; Redundant in Emacs 26 or later, which already highlights macro names.
(defconst use-package-font-lock-keywords
'(("(\\(use-package\\)\\_>[ \t']*\\(\\(?:\\sw\\|\\s_\\)+\\)?"
(1 font-lock-keyword-face)
(2 font-lock-constant-face nil t))))
-
-(font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords)
+(make-obsolete-variable 'use-package-font-lock-keywords
+ 'lisp-el-font-lock-keywords "30.1")
+(when (< emacs-major-version 26)
+ (font-lock-add-keywords 'emacs-lisp-mode use-package-font-lock-keywords))
(defcustom use-package-compute-statistics nil
"If non-nil, compute statistics concerned `use-package' declarations.
@@ -1036,15 +1039,23 @@ meaning:
Configured :config has been processed (the package is loaded!)
Initialized :init has been processed (load status unknown)
Prefaced :preface has been processed
- Declared the use-package declaration was seen"
+ Declared the use-package declaration was seen
+
+Customize the user option `use-package-compute-statistics' to
+enable gathering statistics."
(interactive)
- (with-current-buffer (get-buffer-create "*use-package statistics*")
- (setq tabulated-list-entries
- (mapcar #'use-package-statistics-convert
- (hash-table-keys use-package-statistics)))
- (use-package-statistics-mode)
- (tabulated-list-print)
- (display-buffer (current-buffer))))
+ (let ((statistics (hash-table-keys use-package-statistics)))
+ (unless statistics
+ (if use-package-compute-statistics
+ (user-error "No use-package statistics available")
+ (user-error (concat "Customize `use-package-compute-statistics'"
+ " to enable reporting"))))
+ (with-current-buffer (get-buffer-create "*use-package statistics*")
+ (setq tabulated-list-entries
+ (mapcar #'use-package-statistics-convert statistics))
+ (use-package-statistics-mode)
+ (tabulated-list-print)
+ (display-buffer (current-buffer)))))
(defvar use-package-statistics-status-order
'(("Declared" . 0)
@@ -1055,6 +1066,7 @@ meaning:
(define-derived-mode use-package-statistics-mode tabulated-list-mode
"use-package statistics"
"Show current statistics gathered about `use-package' declarations."
+ :interactive nil
(setq tabulated-list-format
;; The sum of column width is 80 characters:
[("Package" 25 t)
@@ -1152,7 +1164,8 @@ meaning:
#'use-package-normalize-paths))
(defun use-package-handler/:load-path (name _keyword arg rest state)
- (let ((body (use-package-process-keywords name rest state)))
+ (let ((body (use-package-process-keywords name rest
+ (plist-put state :load-path arg))))
(use-package-concat
(mapcar #'(lambda (path)
`(eval-and-compile (add-to-list 'load-path ,path)))
@@ -1578,6 +1591,110 @@ no keyword implies `:all'."
(when use-package-compute-statistics
`((use-package-statistics-gather :config ',name t))))))
+;;;; :vc
+
+(defun use-package-vc-install (arg &optional local-path)
+ "Install a package with `package-vc.el'.
+ARG is a list of the form (NAME OPTIONS REVISION), as returned by
+`use-package-normalize--vc-arg'. If LOCAL-PATH is non-nil, call
+`package-vc-install-from-checkout'; otherwise, indicating a
+remote host, call `package-vc-install' instead."
+ (pcase-let* ((`(,name ,opts ,rev) arg)
+ (spec (if opts (cons name opts) name)))
+ (unless (package-installed-p name)
+ (if local-path
+ (package-vc-install-from-checkout local-path (symbol-name name))
+ (package-vc-install spec rev)))))
+
+(defun use-package-handler/:vc (name _keyword arg rest state)
+ "Generate code to install package NAME, or do so directly.
+When the use-package declaration is part of a byte-compiled file,
+install the package during compilation; otherwise, add it to the
+macro expansion and wait until runtime. The remaining arguments
+are as follows:
+
+_KEYWORD is ignored.
+
+ARG is the normalized input to the `:vc' keyword, as returned by
+the `use-package-normalize/:vc' function.
+
+REST is a plist of other (following) keywords and their
+arguments, each having already been normalized by the respective
+function.
+
+STATE is a plist of any state that keywords processed before
+`:vc' (see `use-package-keywords') may have accumulated.
+
+Also see the Info node `(use-package) Creating an extension'."
+ (let ((body (use-package-process-keywords name rest state))
+ (local-path (car (plist-get state :load-path))))
+ ;; See `use-package-handler/:ensure' for an explanation.
+ (if (bound-and-true-p byte-compile-current-file)
+ (funcall #'use-package-vc-install arg local-path) ; compile time
+ (push `(use-package-vc-install ',arg ,local-path) body)) ; runtime
+ body))
+
+(defun use-package-normalize--vc-arg (arg)
+ "Normalize possible arguments to the `:vc' keyword.
+ARG is a cons-cell of approximately the form that
+`package-vc-selected-packages' accepts, plus an additional `:rev'
+keyword. If `:rev' is not given, it defaults to `:last-release'.
+
+Returns a list (NAME SPEC REV), where (NAME . SPEC) is compliant
+with `package-vc-selected-packages' and REV is a (possibly nil,
+indicating the latest commit) revision."
+ (cl-flet* ((ensure-string (s)
+ (if (and s (stringp s)) s (symbol-name s)))
+ (ensure-symbol (s)
+ (if (and s (stringp s)) (intern s) s))
+ (normalize (k v)
+ (pcase k
+ (:rev (cond ((or (eq v :last-release) (not v)) :last-release)
+ ((eq v :newest) nil)
+ (t (ensure-string v))))
+ (:vc-backend (ensure-symbol v))
+ (_ (ensure-string v)))))
+ (pcase-let ((valid-kws '(:url :branch :lisp-dir :main-file :vc-backend :rev))
+ (`(,name . ,opts) arg))
+ (if (stringp opts) ; (NAME . VERSION-STRING) ?
+ (list name opts)
+ ;; Error handling
+ (cl-loop for (k _) on opts by #'cddr
+ if (not (member k valid-kws))
+ do (use-package-error
+ (format "Keyword :vc received unknown argument: %s. Supported keywords are: %s"
+ k valid-kws)))
+ ;; Actual normalization
+ (list name
+ (cl-loop for (k v) on opts by #'cddr
+ if (not (eq k :rev))
+ nconc (list k (normalize k v)))
+ (normalize :rev (plist-get opts :rev)))))))
+
+(defun use-package-normalize/:vc (name _keyword args)
+ "Normalize possible arguments to the `:vc' keyword.
+NAME is the name of the `use-package' declaration, _KEYWORD is
+ignored, and ARGS it a list of arguments given to the `:vc'
+keyword, the cdr of which is ignored.
+
+See `use-package-normalize--vc-arg' for most of the actual
+normalization work. Also see the Info
+node `(use-package) Creating an extension'."
+ (let ((arg (car args)))
+ (pcase arg
+ ((or 'nil 't) (list name)) ; guess name
+ ((pred symbolp) (list arg)) ; use this name
+ ((pred stringp) (list name arg)) ; version string + guess name
+ ((pred plistp) ; plist + guess name
+ (use-package-normalize--vc-arg (cons name arg)))
+ (`(,(pred symbolp) . ,(or (pred plistp) ; plist/version string + name
+ (pred stringp)))
+ (use-package-normalize--vc-arg arg))
+ (_ (use-package-error "Unrecognized argument to :vc.\
+ The keyword wants an argument of nil, t, a name of a package,\
+ or a cons-cell as accepted by `package-vc-selected-packages', where \
+ the accepted plist is augmented by a `:rev' keyword.")))))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;; The main macro
@@ -1667,7 +1784,9 @@ Usage:
(compare with `custom-set-variables').
:custom-face Call `custom-set-faces' with each face definition.
:ensure Loads the package using package.el if necessary.
-:pin Pin the package to an archive."
+:pin Pin the package to an archive.
+:vc Install the package directly from a version control system
+ (using `package-vc.el')."
(declare (indent defun))
(unless (memq :disabled args)
(macroexp-progn