diff options
author | Tom Tromey <tromey@redhat.com> | 2013-07-06 23:18:58 -0600 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2013-07-06 23:18:58 -0600 |
commit | 6dacdad5fcb278e5a16b38bb81786aac9ca27be4 (patch) | |
tree | f5f331ea361ba0f99e0f9b638d183ad492a7da31 /lisp/emacs-lisp | |
parent | 0a6f2ff0c8ceb29703e76cddd46ea3f176dd873a (diff) | |
parent | 219afb88d9d484393418820d1c08dc93299110ec (diff) | |
download | emacs-6dacdad5fcb278e5a16b38bb81786aac9ca27be4.tar.gz emacs-6dacdad5fcb278e5a16b38bb81786aac9ca27be4.tar.bz2 emacs-6dacdad5fcb278e5a16b38bb81786aac9ca27be4.zip |
merge from trunk
this merges frmo trunk and fixes various build issues.
this needed a few ugly tweaks.
this hangs in "make check" now
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/autoload.el | 134 | ||||
-rw-r--r-- | lisp/emacs-lisp/byte-opt.el | 1 | ||||
-rw-r--r-- | lisp/emacs-lisp/bytecomp.el | 39 | ||||
-rw-r--r-- | lisp/emacs-lisp/cconv.el | 14 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-lib.el | 12 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-loaddefs.el | 1285 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-macs.el | 12 | ||||
-rw-r--r-- | lisp/emacs-lisp/cl-seq.el | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/eieio-custom.el | 3 | ||||
-rw-r--r-- | lisp/emacs-lisp/eieio.el | 7 | ||||
-rw-r--r-- | lisp/emacs-lisp/generic.el | 7 | ||||
-rw-r--r-- | lisp/emacs-lisp/lisp-mode.el | 4 | ||||
-rw-r--r-- | lisp/emacs-lisp/lisp.el | 6 | ||||
-rw-r--r-- | lisp/emacs-lisp/map-ynp.el | 48 | ||||
-rw-r--r-- | lisp/emacs-lisp/nadvice.el | 80 | ||||
-rw-r--r-- | lisp/emacs-lisp/package-x.el | 12 | ||||
-rw-r--r-- | lisp/emacs-lisp/package.el | 1195 | ||||
-rw-r--r-- | lisp/emacs-lisp/tabulated-list.el | 30 |
18 files changed, 807 insertions, 2084 deletions
diff --git a/lisp/emacs-lisp/autoload.el b/lisp/emacs-lisp/autoload.el index dbb4a239f02..22713c6589c 100644 --- a/lisp/emacs-lisp/autoload.el +++ b/lisp/emacs-lisp/autoload.el @@ -31,6 +31,7 @@ ;;; Code: (require 'lisp-mode) ;for `doc-string-elt' properties. +(require 'lisp-mnt) (require 'help-fns) ;for help-add-fundoc-usage. (eval-when-compile (require 'cl-lib)) @@ -435,6 +436,64 @@ Return non-nil in the case where no autoloads were added at point." (defvar print-readably) +(defun autoload--insert-text (output-start otherbuf outbuf absfile + load-name printfun) + ;; If not done yet, figure out where to insert this text. + (unless (marker-buffer output-start) + (let ((outbuf + (or (if otherbuf + ;; A file-local setting of + ;; autoload-generated-file says we + ;; should ignore OUTBUF. + nil + outbuf) + (autoload-find-destination absfile load-name) + ;; The file has autoload cookies, but they're + ;; already up-to-date. If OUTFILE is nil, the + ;; entries are in the expected OUTBUF, + ;; otherwise they're elsewhere. + (throw 'done otherbuf)))) + (with-current-buffer outbuf + (move-marker output-start (point) outbuf)))) + (let ((standard-output (marker-buffer output-start))) + (funcall printfun))) + +(defun autoload--insert-cookie-text (output-start otherbuf outbuf absfile + load-name file) + (autoload--insert-text + output-start otherbuf outbuf absfile load-name + (lambda () + (search-forward generate-autoload-cookie) + (skip-chars-forward " \t") + (if (eolp) + (condition-case-unless-debug err + ;; Read the next form and make an autoload. + (let* ((form (prog1 (read (current-buffer)) + (or (bolp) (forward-line 1)))) + (autoload (make-autoload form load-name))) + (if autoload + nil + (setq autoload form)) + (let ((autoload-print-form-outbuf + standard-output)) + (autoload-print-form autoload))) + (error + (message "Autoload cookie error in %s:%s %S" + file (count-lines (point-min) (point)) err))) + + ;; Copy the rest of the line to the output. + (princ (buffer-substring + (progn + ;; Back up over whitespace, to preserve it. + (skip-chars-backward " \f\t") + (if (= (char-after (1+ (point))) ? ) + ;; Eat one space. + (forward-char 1)) + (point)) + (progn (forward-line 1) (point)))))))) + +(defvar autoload-builtin-package-versions nil) + ;; When called from `generate-file-autoloads' we should ignore ;; `generated-autoload-file' altogether. When called from ;; `update-file-autoloads' we don't know `outbuf'. And when called from @@ -456,8 +515,7 @@ different from OUTFILE, then OUTBUF is ignored. Return non-nil if and only if FILE adds no autoloads to OUTFILE \(or OUTBUF if OUTFILE is nil)." (catch 'done - (let ((autoloads-done '()) - load-name + (let (load-name (print-length nil) (print-level nil) (print-readably t) ; This does something in Lucid Emacs. @@ -466,7 +524,7 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE (otherbuf nil) (absfile (expand-file-name file)) ;; nil until we found a cookie. - output-start ostart) + output-start) (with-current-buffer (or visited ;; It is faster to avoid visiting the file. (autoload-find-file file)) @@ -487,58 +545,31 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE (save-excursion (save-restriction (widen) + (when autoload-builtin-package-versions + (let ((version (lm-header "version")) + package) + (and version + (setq version (ignore-errors (version-to-list version))) + (setq package (or (lm-header "package") + (file-name-sans-extension + (file-name-nondirectory file)))) + (setq output-start (make-marker)) + (autoload--insert-text + output-start otherbuf outbuf absfile load-name + (lambda () + (princ `(push (purecopy + ',(cons (intern package) version)) + package--builtin-versions)) + (newline)))))) + (goto-char (point-min)) (while (not (eobp)) (skip-chars-forward " \t\n\f") (cond ((looking-at (regexp-quote generate-autoload-cookie)) - ;; If not done yet, figure out where to insert this text. - (unless output-start - (let ((outbuf - (or (if otherbuf - ;; A file-local setting of - ;; autoload-generated-file says we - ;; should ignore OUTBUF. - nil - outbuf) - (autoload-find-destination absfile load-name) - ;; The file has autoload cookies, but they're - ;; already up-to-date. If OUTFILE is nil, the - ;; entries are in the expected OUTBUF, - ;; otherwise they're elsewhere. - (throw 'done otherbuf)))) - (with-current-buffer outbuf - (setq output-start (point-marker) - ostart (point))))) - (search-forward generate-autoload-cookie) - (skip-chars-forward " \t") - (if (eolp) - (condition-case-unless-debug err - ;; Read the next form and make an autoload. - (let* ((form (prog1 (read (current-buffer)) - (or (bolp) (forward-line 1)))) - (autoload (make-autoload form load-name))) - (if autoload - (push (nth 1 form) autoloads-done) - (setq autoload form)) - (let ((autoload-print-form-outbuf - (marker-buffer output-start))) - (autoload-print-form autoload))) - (error - (message "Autoload cookie error in %s:%s %S" - file (count-lines (point-min) (point)) err))) - - ;; Copy the rest of the line to the output. - (princ (buffer-substring - (progn - ;; Back up over whitespace, to preserve it. - (skip-chars-backward " \f\t") - (if (= (char-after (1+ (point))) ? ) - ;; Eat one space. - (forward-char 1)) - (point)) - (progn (forward-line 1) (point))) - (marker-buffer output-start)))) + (unless output-start (setq output-start (make-marker))) + (autoload--insert-cookie-text + output-start otherbuf outbuf absfile load-name file)) ((looking-at ";") ;; Don't read the comment. (forward-line 1)) @@ -553,12 +584,11 @@ Return non-nil if and only if FILE adds no autoloads to OUTFILE (save-excursion ;; Insert the section-header line which lists the file name ;; and which functions are in it, etc. - (cl-assert (= ostart output-start)) (goto-char output-start) (let ((relfile (file-relative-name absfile))) (autoload-insert-section-header (marker-buffer output-start) - autoloads-done load-name relfile + () load-name relfile (if secondary-autoloads-file-buf ;; MD5 checksums are much better because they do not ;; change unless the file changes (so they'll be diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 7375c2176ba..7214501362d 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -287,6 +287,7 @@ (byte-compile--reify-function fn))))) (if (eq (car-safe newfn) 'function) (byte-compile-unfold-lambda `(,(cadr newfn) ,@(cdr form))) + ;; This can happen because of macroexp-warn-and-return &co. (byte-compile-log-warning (format "Inlining closure %S failed" name)) form)))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index e603f76f41d..f4e79dc4886 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -2174,6 +2174,8 @@ list that represents a doc string reference. byte-compile-maxdepth 0 byte-compile-output nil)))) +(defvar byte-compile-force-lexical-warnings nil) + (defun byte-compile-preprocess (form &optional _for-effect) (setq form (macroexpand-all form byte-compile-macro-environment)) ;; FIXME: We should run byte-optimize-form here, but it currently does not @@ -2182,9 +2184,10 @@ list that represents a doc string reference. ;; macroexpand-all. ;; (if (memq byte-optimize '(t source)) ;; (setq form (byte-optimize-form form for-effect))) - (if lexical-binding - (cconv-closure-convert form) - form)) + (cond + (lexical-binding (cconv-closure-convert form)) + (byte-compile-force-lexical-warnings (cconv-warnings-only form)) + (t form))) ;; byte-hunk-handlers cannot call this! (defun byte-compile-toplevel-file-form (form) @@ -2212,7 +2215,7 @@ list that represents a doc string reference. (and (let ((form form)) (while (if (setq form (cdr form)) (macroexp-const-p (car form)))) (null form)) ;Constants only - (eval (nth 5 form)) ;Macro + (memq (eval (nth 5 form)) '(t macro)) ;Macro (eval form)) ;Define the autoload. ;; Avoid undefined function warnings for the autoload. (when (and (consp (nth 1 form)) @@ -4184,7 +4187,7 @@ binding slots have been popped." (byte-compile-set-symbol-position 'autoload) (and (macroexp-const-p (nth 1 form)) (macroexp-const-p (nth 5 form)) - (eval (nth 5 form)) ; macro-p + (memq (eval (nth 5 form)) '(t macro)) ; macro-p (not (fboundp (eval (nth 1 form)))) (byte-compile-warn "The compiler ignores `autoload' except at top level. You should @@ -4240,6 +4243,12 @@ binding slots have been popped." lam)) (unless (byte-compile-file-form-defmumble name macro arglist body rest) + (when macro + (if (null fun) + (message "Macro %s unrecognized, won't work in file" name) + (message "Macro %s partly recognized, trying our luck" name) + (push (cons name (eval fun)) + byte-compile-macro-environment))) (byte-compile-keep-pending form)))) ;; We used to just do: (byte-compile-normal-call form) @@ -4268,26 +4277,6 @@ binding slots have been popped." 'byte-hunk-handler 'byte-compile-form-make-variable-buffer-local) (defun byte-compile-form-make-variable-buffer-local (form) (byte-compile-keep-pending form 'byte-compile-normal-call)) - -(byte-defop-compiler-1 add-to-list byte-compile-add-to-list) -(defun byte-compile-add-to-list (form) - ;; FIXME: This could be used for `set' as well, except that it's got - ;; its own opcode, so the final `byte-compile-normal-call' needs to - ;; be replaced with something else. - (pcase form - (`(,fun ',var . ,_) - (byte-compile-check-variable var 'assign) - (if (assq var byte-compile--lexical-environment) - (byte-compile-log-warning - (format "%s cannot use lexical var `%s'" fun var) - nil :error) - (unless (or (not (byte-compile-warning-enabled-p 'free-vars)) - (boundp var) - (memq var byte-compile-bound-variables) - (memq var byte-compile-free-references)) - (byte-compile-warn "assignment to free variable `%S'" var) - (push var byte-compile-free-references))))) - (byte-compile-normal-call form)) ;;; tags diff --git a/lisp/emacs-lisp/cconv.el b/lisp/emacs-lisp/cconv.el index 761e33c059d..70fa71a0da4 100644 --- a/lisp/emacs-lisp/cconv.el +++ b/lisp/emacs-lisp/cconv.el @@ -143,7 +143,19 @@ Returns a form where all lambdas don't have any free variables." ;; Analyze form - fill these variables with new information. (cconv-analyse-form form '()) (setq cconv-freevars-alist (nreverse cconv-freevars-alist)) - (cconv-convert form nil nil))) ; Env initially empty. + (prog1 (cconv-convert form nil nil) ; Env initially empty. + (cl-assert (null cconv-freevars-alist))))) + +;;;###autoload +(defun cconv-warnings-only (form) + "Add the warnings that closure conversion would encounter." + (let ((cconv-freevars-alist '()) + (cconv-lambda-candidates '()) + (cconv-captured+mutated '())) + ;; Analyze form - fill these variables with new information. + (cconv-analyse-form form '()) + ;; But don't perform the closure conversion. + form)) (defconst cconv--dummy-var (make-symbol "ignored")) diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el index 52f123c83ec..2ab6b7ad089 100644 --- a/lisp/emacs-lisp/cl-lib.el +++ b/lisp/emacs-lisp/cl-lib.el @@ -36,13 +36,6 @@ ;; package which should always be present. -;;; Future notes: - -;; Once Emacs 19 becomes standard, many things in this package which are -;; messy for reasons of compatibility can be greatly simplified. For now, -;; I prefer to maintain one unified version. - - ;;; Change Log: ;; Version 2.02 (30 Jul 93): @@ -732,9 +725,10 @@ If ALIST is non-nil, the new pairs are prepended to it." (put 'cl-defsubst 'doc-string-elt 3) (put 'cl-defstruct 'doc-string-elt 2)) -(load "cl-loaddefs" nil 'quiet) - (provide 'cl-lib) +(or (load "cl-loaddefs" 'noerror 'quiet) + ;; When bootstrapping, cl-loaddefs hasn't been built yet! + (require 'cl-macs)) ;; Local variables: ;; byte-compile-dynamic: t diff --git a/lisp/emacs-lisp/cl-loaddefs.el b/lisp/emacs-lisp/cl-loaddefs.el deleted file mode 100644 index a06abb03b95..00000000000 --- a/lisp/emacs-lisp/cl-loaddefs.el +++ /dev/null @@ -1,1285 +0,0 @@ -;;; cl-loaddefs.el --- automatically extracted autoloads -;; -;;; Code: - - -;;;### (autoloads (cl-prettyexpand cl-remprop cl--do-remf cl--set-getf -;;;;;; cl-getf cl-get cl-tailp cl-list-length cl-nreconc cl-revappend -;;;;;; cl-concatenate cl-subseq cl-float-limits cl-random-state-p -;;;;;; cl-make-random-state cl-random cl-signum cl-rem cl-mod cl-round -;;;;;; cl-truncate cl-ceiling cl-floor cl-isqrt cl-lcm cl-gcd cl--set-frame-visible-p -;;;;;; cl--map-overlays cl--map-intervals cl--map-keymap-recursively -;;;;;; cl-notevery cl-notany cl-every cl-some cl-mapcon cl-mapcan -;;;;;; cl-mapl cl-mapc cl-maplist cl-map cl--mapcar-many cl-equalp -;;;;;; cl-coerce) "cl-extra" "cl-extra.el" "011111887a1f353218e59e14d0b09c68") -;;; Generated autoloads from cl-extra.el - -(autoload 'cl-coerce "cl-extra" "\ -Coerce OBJECT to type TYPE. -TYPE is a Common Lisp type specifier. - -\(fn OBJECT TYPE)" nil nil) - -(autoload 'cl-equalp "cl-extra" "\ -Return t if two Lisp objects have similar structures and contents. -This is like `equal', except that it accepts numerically equal -numbers of different types (float vs. integer), and also compares -strings case-insensitively. - -\(fn X Y)" nil nil) - -(autoload 'cl--mapcar-many "cl-extra" "\ - - -\(fn CL-FUNC CL-SEQS)" nil nil) - -(autoload 'cl-map "cl-extra" "\ -Map a FUNCTION across one or more SEQUENCEs, returning a sequence. -TYPE is the sequence type to return. - -\(fn TYPE FUNCTION SEQUENCE...)" nil nil) - -(autoload 'cl-maplist "cl-extra" "\ -Map FUNCTION to each sublist of LIST or LISTs. -Like `cl-mapcar', except applies to lists and their cdr's rather than to -the elements themselves. - -\(fn FUNCTION LIST...)" nil nil) - -(autoload 'cl-mapc "cl-extra" "\ -Like `cl-mapcar', but does not accumulate values returned by the function. - -\(fn FUNCTION SEQUENCE...)" nil nil) - -(autoload 'cl-mapl "cl-extra" "\ -Like `cl-maplist', but does not accumulate values returned by the function. - -\(fn FUNCTION LIST...)" nil nil) - -(autoload 'cl-mapcan "cl-extra" "\ -Like `cl-mapcar', but nconc's together the values returned by the function. - -\(fn FUNCTION SEQUENCE...)" nil nil) - -(autoload 'cl-mapcon "cl-extra" "\ -Like `cl-maplist', but nconc's together the values returned by the function. - -\(fn FUNCTION LIST...)" nil nil) - -(autoload 'cl-some "cl-extra" "\ -Return true if PREDICATE is true of any element of SEQ or SEQs. -If so, return the true (non-nil) value returned by PREDICATE. - -\(fn PREDICATE SEQ...)" nil nil) - -(autoload 'cl-every "cl-extra" "\ -Return true if PREDICATE is true of every element of SEQ or SEQs. - -\(fn PREDICATE SEQ...)" nil nil) - -(autoload 'cl-notany "cl-extra" "\ -Return true if PREDICATE is false of every element of SEQ or SEQs. - -\(fn PREDICATE SEQ...)" nil nil) - -(autoload 'cl-notevery "cl-extra" "\ -Return true if PREDICATE is false of some element of SEQ or SEQs. - -\(fn PREDICATE SEQ...)" nil nil) - -(autoload 'cl--map-keymap-recursively "cl-extra" "\ - - -\(fn CL-FUNC-REC CL-MAP &optional CL-BASE)" nil nil) - -(autoload 'cl--map-intervals "cl-extra" "\ - - -\(fn CL-FUNC &optional CL-WHAT CL-PROP CL-START CL-END)" nil nil) - -(autoload 'cl--map-overlays "cl-extra" "\ - - -\(fn CL-FUNC &optional CL-BUFFER CL-START CL-END CL-ARG)" nil nil) - -(autoload 'cl--set-frame-visible-p "cl-extra" "\ - - -\(fn FRAME VAL)" nil nil) - -(autoload 'cl-gcd "cl-extra" "\ -Return the greatest common divisor of the arguments. - -\(fn &rest ARGS)" nil nil) - -(autoload 'cl-lcm "cl-extra" "\ -Return the least common multiple of the arguments. - -\(fn &rest ARGS)" nil nil) - -(autoload 'cl-isqrt "cl-extra" "\ -Return the integer square root of the argument. - -\(fn X)" nil nil) - -(autoload 'cl-floor "cl-extra" "\ -Return a list of the floor of X and the fractional part of X. -With two arguments, return floor and remainder of their quotient. - -\(fn X &optional Y)" nil nil) - -(autoload 'cl-ceiling "cl-extra" "\ -Return a list of the ceiling of X and the fractional part of X. -With two arguments, return ceiling and remainder of their quotient. - -\(fn X &optional Y)" nil nil) - -(autoload 'cl-truncate "cl-extra" "\ -Return a list of the integer part of X and the fractional part of X. -With two arguments, return truncation and remainder of their quotient. - -\(fn X &optional Y)" nil nil) - -(autoload 'cl-round "cl-extra" "\ -Return a list of X rounded to the nearest integer and the remainder. -With two arguments, return rounding and remainder of their quotient. - -\(fn X &optional Y)" nil nil) - -(autoload 'cl-mod "cl-extra" "\ -The remainder of X divided by Y, with the same sign as Y. - -\(fn X Y)" nil nil) - -(autoload 'cl-rem "cl-extra" "\ -The remainder of X divided by Y, with the same sign as X. - -\(fn X Y)" nil nil) - -(autoload 'cl-signum "cl-extra" "\ -Return 1 if X is positive, -1 if negative, 0 if zero. - -\(fn X)" nil nil) - -(autoload 'cl-random "cl-extra" "\ -Return a random nonnegative number less than LIM, an integer or float. -Optional second arg STATE is a random-state object. - -\(fn LIM &optional STATE)" nil nil) - -(autoload 'cl-make-random-state "cl-extra" "\ -Return a copy of random-state STATE, or of the internal state if omitted. -If STATE is t, return a new state object seeded from the time of day. - -\(fn &optional STATE)" nil nil) - -(autoload 'cl-random-state-p "cl-extra" "\ -Return t if OBJECT is a random-state object. - -\(fn OBJECT)" nil nil) - -(autoload 'cl-float-limits "cl-extra" "\ -Initialize the Common Lisp floating-point parameters. -This sets the values of: `cl-most-positive-float', `cl-most-negative-float', -`cl-least-positive-float', `cl-least-negative-float', `cl-float-epsilon', -`cl-float-negative-epsilon', `cl-least-positive-normalized-float', and -`cl-least-negative-normalized-float'. - -\(fn)" nil nil) - -(autoload 'cl-subseq "cl-extra" "\ -Return the subsequence of SEQ from START to END. -If END is omitted, it defaults to the length of the sequence. -If START or END is negative, it counts from the end. - -\(fn SEQ START &optional END)" nil nil) - -(autoload 'cl-concatenate "cl-extra" "\ -Concatenate, into a sequence of type TYPE, the argument SEQUENCEs. - -\(fn TYPE SEQUENCE...)" nil nil) - -(autoload 'cl-revappend "cl-extra" "\ -Equivalent to (append (reverse X) Y). - -\(fn X Y)" nil nil) - -(autoload 'cl-nreconc "cl-extra" "\ -Equivalent to (nconc (nreverse X) Y). - -\(fn X Y)" nil nil) - -(autoload 'cl-list-length "cl-extra" "\ -Return the length of list X. Return nil if list is circular. - -\(fn X)" nil nil) - -(autoload 'cl-tailp "cl-extra" "\ -Return true if SUBLIST is a tail of LIST. - -\(fn SUBLIST LIST)" nil nil) - -(autoload 'cl-get "cl-extra" "\ -Return the value of SYMBOL's PROPNAME property, or DEFAULT if none. - -\(fn SYMBOL PROPNAME &optional DEFAULT)" nil nil) - -(eval-and-compile (put 'cl-get 'compiler-macro #'cl--compiler-macro-get)) - -(autoload 'cl-getf "cl-extra" "\ -Search PROPLIST for property PROPNAME; return its value or DEFAULT. -PROPLIST is a list of the sort returned by `symbol-plist'. - -\(fn PROPLIST PROPNAME &optional DEFAULT)" nil nil) - -(autoload 'cl--set-getf "cl-extra" "\ - - -\(fn PLIST TAG VAL)" nil nil) - -(autoload 'cl--do-remf "cl-extra" "\ - - -\(fn PLIST TAG)" nil nil) - -(autoload 'cl-remprop "cl-extra" "\ -Remove from SYMBOL's plist the property PROPNAME and its value. - -\(fn SYMBOL PROPNAME)" nil nil) - -(autoload 'cl-prettyexpand "cl-extra" "\ -Expand macros in FORM and insert the pretty-printed result. -Optional argument FULL non-nil means to expand all macros, -including `cl-block' and `cl-eval-when'. - -\(fn FORM &optional FULL)" nil nil) - -;;;*** - -;;;### (autoloads (cl--compiler-macro-adjoin cl-defsubst cl-compiler-macroexpand -;;;;;; cl-define-compiler-macro cl-assert cl-check-type cl-typep -;;;;;; cl-deftype cl-defstruct cl-callf2 cl-callf cl-letf* cl-letf -;;;;;; cl-rotatef cl-shiftf cl-remf cl-psetf cl-declare cl-the cl-locally -;;;;;; cl-multiple-value-setq cl-multiple-value-bind cl-symbol-macrolet -;;;;;; cl-macrolet cl-labels cl-flet* cl-flet cl-progv cl-psetq -;;;;;; cl-do-all-symbols cl-do-symbols cl-tagbody cl-dotimes cl-dolist -;;;;;; cl-do* cl-do cl-loop cl-return-from cl-return cl-block cl-etypecase -;;;;;; cl-typecase cl-ecase cl-case cl-load-time-value cl-eval-when -;;;;;; cl-destructuring-bind cl-function cl-defmacro cl-defun cl-gentemp -;;;;;; cl-gensym cl--compiler-macro-cXXr cl--compiler-macro-list*) -;;;;;; "cl-macs" "cl-macs.el" "fd824d987086eafec0b1cb2efa8312f4") -;;; Generated autoloads from cl-macs.el - -(autoload 'cl--compiler-macro-list* "cl-macs" "\ - - -\(fn FORM ARG &rest OTHERS)" nil nil) - -(autoload 'cl--compiler-macro-cXXr "cl-macs" "\ - - -\(fn FORM X)" nil nil) - -(autoload 'cl-gensym "cl-macs" "\ -Generate a new uninterned symbol. -The name is made by appending a number to PREFIX, default \"G\". - -\(fn &optional PREFIX)" nil nil) - -(autoload 'cl-gentemp "cl-macs" "\ -Generate a new interned symbol with a unique name. -The name is made by appending a number to PREFIX, default \"G\". - -\(fn &optional PREFIX)" nil nil) - -(autoload 'cl-defun "cl-macs" "\ -Define NAME as a function. -Like normal `defun', except ARGLIST allows full Common Lisp conventions, -and BODY is implicitly surrounded by (cl-block NAME ...). - -\(fn NAME ARGLIST [DOCSTRING] BODY...)" nil t) - -(put 'cl-defun 'doc-string-elt '3) - -(put 'cl-defun 'lisp-indent-function '2) - -(autoload 'cl-defmacro "cl-macs" "\ -Define NAME as a macro. -Like normal `defmacro', except ARGLIST allows full Common Lisp conventions, -and BODY is implicitly surrounded by (cl-block NAME ...). - -\(fn NAME ARGLIST [DOCSTRING] BODY...)" nil t) - -(put 'cl-defmacro 'doc-string-elt '3) - -(put 'cl-defmacro 'lisp-indent-function '2) - -(autoload 'cl-function "cl-macs" "\ -Introduce a function. -Like normal `function', except that if argument is a lambda form, -its argument list allows full Common Lisp conventions. - -\(fn FUNC)" nil t) - -(autoload 'cl-destructuring-bind "cl-macs" "\ -Bind the variables in ARGS to the result of EXPR and execute BODY. - -\(fn ARGS EXPR &rest BODY)" nil t) - -(put 'cl-destructuring-bind 'lisp-indent-function '2) - -(autoload 'cl-eval-when "cl-macs" "\ -Control when BODY is evaluated. -If `compile' is in WHEN, BODY is evaluated when compiled at top-level. -If `load' is in WHEN, BODY is evaluated when loaded after top-level compile. -If `eval' is in WHEN, BODY is evaluated when interpreted or at non-top-level. - -\(fn (WHEN...) BODY...)" nil t) - -(put 'cl-eval-when 'lisp-indent-function '1) - -(autoload 'cl-load-time-value "cl-macs" "\ -Like `progn', but evaluates the body at load time. -The result of the body appears to the compiler as a quoted constant. - -\(fn FORM &optional READ-ONLY)" nil t) - -(autoload 'cl-case "cl-macs" "\ -Eval EXPR and choose among clauses on that value. -Each clause looks like (KEYLIST BODY...). EXPR is evaluated and compared -against each key in each KEYLIST; the corresponding BODY is evaluated. -If no clause succeeds, cl-case returns nil. A single atom may be used in -place of a KEYLIST of one atom. A KEYLIST of t or `otherwise' is -allowed only in the final clause, and matches if no other keys match. -Key values are compared by `eql'. - -\(fn EXPR (KEYLIST BODY...)...)" nil t) - -(put 'cl-case 'lisp-indent-function '1) - -(autoload 'cl-ecase "cl-macs" "\ -Like `cl-case', but error if no case fits. -`otherwise'-clauses are not allowed. - -\(fn EXPR (KEYLIST BODY...)...)" nil t) - -(put 'cl-ecase 'lisp-indent-function '1) - -(autoload 'cl-typecase "cl-macs" "\ -Evals EXPR, chooses among clauses on that value. -Each clause looks like (TYPE BODY...). EXPR is evaluated and, if it -satisfies TYPE, the corresponding BODY is evaluated. If no clause succeeds, -cl-typecase returns nil. A TYPE of t or `otherwise' is allowed only in the -final clause, and matches if no other keys match. - -\(fn EXPR (TYPE BODY...)...)" nil t) - -(put 'cl-typecase 'lisp-indent-function '1) - -(autoload 'cl-etypecase "cl-macs" "\ -Like `cl-typecase', but error if no case fits. -`otherwise'-clauses are not allowed. - -\(fn EXPR (TYPE BODY...)...)" nil t) - -(put 'cl-etypecase 'lisp-indent-function '1) - -(autoload 'cl-block "cl-macs" "\ -Define a lexically-scoped block named NAME. -NAME may be any symbol. Code inside the BODY forms can call `cl-return-from' -to jump prematurely out of the block. This differs from `catch' and `throw' -in two respects: First, the NAME is an unevaluated symbol rather than a -quoted symbol or other form; and second, NAME is lexically rather than -dynamically scoped: Only references to it within BODY will work. These -references may appear inside macro expansions, but not inside functions -called from BODY. - -\(fn NAME &rest BODY)" nil t) - -(put 'cl-block 'lisp-indent-function '1) - -(autoload 'cl-return "cl-macs" "\ -Return from the block named nil. -This is equivalent to `(cl-return-from nil RESULT)'. - -\(fn &optional RESULT)" nil t) - -(autoload 'cl-return-from "cl-macs" "\ -Return from the block named NAME. -This jumps out to the innermost enclosing `(cl-block NAME ...)' form, -returning RESULT from that form (or nil if RESULT is omitted). -This is compatible with Common Lisp, but note that `defun' and -`defmacro' do not create implicit blocks as they do in Common Lisp. - -\(fn NAME &optional RESULT)" nil t) - -(put 'cl-return-from 'lisp-indent-function '1) - -(autoload 'cl-loop "cl-macs" "\ -The Common Lisp `loop' macro. -Valid clauses include: - For clauses: - for VAR from/upfrom/downfrom EXPR1 to/upto/downto/above/below EXPR2 by EXPR3 - for VAR = EXPR1 then EXPR2 - for VAR in/on/in-ref LIST by FUNC - for VAR across/across-ref ARRAY - for VAR being: - the elements of/of-ref SEQUENCE [using (index VAR2)] - the symbols [of OBARRAY] - the hash-keys/hash-values of HASH-TABLE [using (hash-values/hash-keys V2)] - the key-codes/key-bindings/key-seqs of KEYMAP [using (key-bindings VAR2)] - the overlays/intervals [of BUFFER] [from POS1] [to POS2] - the frames/buffers - the windows [of FRAME] - Iteration clauses: - repeat INTEGER - while/until/always/never/thereis CONDITION - Accumulation clauses: - collect/append/nconc/concat/vconcat/count/sum/maximize/minimize FORM - [into VAR] - Miscellaneous clauses: - with VAR = INIT - if/when/unless COND CLAUSE [and CLAUSE]... else CLAUSE [and CLAUSE...] - named NAME - initially/finally [do] EXPRS... - do EXPRS... - [finally] return EXPR - -For more details, see Info node `(cl)Loop Facility'. - -\(fn CLAUSE...)" nil t) - -(autoload 'cl-do "cl-macs" "\ -The Common Lisp `do' loop. - -\(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" nil t) - -(put 'cl-do 'lisp-indent-function '2) - -(autoload 'cl-do* "cl-macs" "\ -The Common Lisp `do*' loop. - -\(fn ((VAR INIT [STEP])...) (END-TEST [RESULT...]) BODY...)" nil t) - -(put 'cl-do* 'lisp-indent-function '2) - -(autoload 'cl-dolist "cl-macs" "\ -Loop over a list. -Evaluate BODY with VAR bound to each `car' from LIST, in turn. -Then evaluate RESULT to get return value, default nil. -An implicit nil block is established around the loop. - -\(fn (VAR LIST [RESULT]) BODY...)" nil t) - -(put 'cl-dolist 'lisp-indent-function '1) - -(autoload 'cl-dotimes "cl-macs" "\ -Loop a certain number of times. -Evaluate BODY with VAR bound to successive integers from 0, inclusive, -to COUNT, exclusive. Then evaluate RESULT to get return value, default -nil. - -\(fn (VAR COUNT [RESULT]) BODY...)" nil t) - -(put 'cl-dotimes 'lisp-indent-function '1) - -(autoload 'cl-tagbody "cl-macs" "\ -Execute statements while providing for control transfers to labels. -Each element of LABELS-OR-STMTS can be either a label (integer or symbol) -or a `cons' cell, in which case it's taken to be a statement. -This distinction is made before performing macroexpansion. -Statements are executed in sequence left to right, discarding any return value, -stopping only when reaching the end of LABELS-OR-STMTS. -Any statement can transfer control at any time to the statements that follow -one of the labels with the special form (go LABEL). -Labels have lexical scope and dynamic extent. - -\(fn &rest LABELS-OR-STMTS)" nil t) - -(autoload 'cl-do-symbols "cl-macs" "\ -Loop over all symbols. -Evaluate BODY with VAR bound to each interned symbol, or to each symbol -from OBARRAY. - -\(fn (VAR [OBARRAY [RESULT]]) BODY...)" nil t) - -(put 'cl-do-symbols 'lisp-indent-function '1) - -(autoload 'cl-do-all-symbols "cl-macs" "\ -Like `cl-do-symbols', but use the default obarray. - -\(fn (VAR [RESULT]) BODY...)" nil t) - -(put 'cl-do-all-symbols 'lisp-indent-function '1) - -(autoload 'cl-psetq "cl-macs" "\ -Set SYMs to the values VALs in parallel. -This is like `setq', except that all VAL forms are evaluated (in order) -before assigning any symbols SYM to the corresponding values. - -\(fn SYM VAL SYM VAL ...)" nil t) - -(autoload 'cl-progv "cl-macs" "\ -Bind SYMBOLS to VALUES dynamically in BODY. -The forms SYMBOLS and VALUES are evaluated, and must evaluate to lists. -Each symbol in the first list is bound to the corresponding value in the -second list (or to nil if VALUES is shorter than SYMBOLS); then the -BODY forms are executed and their result is returned. This is much like -a `let' form, except that the list of symbols can be computed at run-time. - -\(fn SYMBOLS VALUES &rest BODY)" nil t) - -(put 'cl-progv 'lisp-indent-function '2) - -(autoload 'cl-flet "cl-macs" "\ -Make local function definitions. -Like `cl-labels' but the definitions are not recursive. - -\(fn ((FUNC ARGLIST BODY...) ...) FORM...)" nil t) - -(put 'cl-flet 'lisp-indent-function '1) - -(autoload 'cl-flet* "cl-macs" "\ -Make local function definitions. -Like `cl-flet' but the definitions can refer to previous ones. - -\(fn ((FUNC ARGLIST BODY...) ...) FORM...)" nil t) - -(put 'cl-flet* 'lisp-indent-function '1) - -(autoload 'cl-labels "cl-macs" "\ -Make temporary function bindings. -The bindings can be recursive and the scoping is lexical, but capturing them -in closures will only work if `lexical-binding' is in use. - -\(fn ((FUNC ARGLIST BODY...) ...) FORM...)" nil t) - -(put 'cl-labels 'lisp-indent-function '1) - -(autoload 'cl-macrolet "cl-macs" "\ -Make temporary macro definitions. -This is like `cl-flet', but for macros instead of functions. - -\(fn ((NAME ARGLIST BODY...) ...) FORM...)" nil t) - -(put 'cl-macrolet 'lisp-indent-function '1) - -(autoload 'cl-symbol-macrolet "cl-macs" "\ -Make symbol macro definitions. -Within the body FORMs, references to the variable NAME will be replaced -by EXPANSION, and (setq NAME ...) will act like (setf EXPANSION ...). - -\(fn ((NAME EXPANSION) ...) FORM...)" nil t) - -(put 'cl-symbol-macrolet 'lisp-indent-function '1) - -(autoload 'cl-multiple-value-bind "cl-macs" "\ -Collect multiple return values. -FORM must return a list; the BODY is then executed with the first N elements -of this list bound (`let'-style) to each of the symbols SYM in turn. This -is analogous to the Common Lisp `cl-multiple-value-bind' macro, using lists to -simulate true multiple return values. For compatibility, (cl-values A B C) is -a synonym for (list A B C). - -\(fn (SYM...) FORM BODY)" nil t) - -(put 'cl-multiple-value-bind 'lisp-indent-function '2) - -(autoload 'cl-multiple-value-setq "cl-macs" "\ -Collect multiple return values. -FORM must return a list; the first N elements of this list are stored in -each of the symbols SYM in turn. This is analogous to the Common Lisp -`cl-multiple-value-setq' macro, using lists to simulate true multiple return -values. For compatibility, (cl-values A B C) is a synonym for (list A B C). - -\(fn (SYM...) FORM)" nil t) - -(put 'cl-multiple-value-setq 'lisp-indent-function '1) - -(autoload 'cl-locally "cl-macs" "\ -Equivalent to `progn'. - -\(fn &rest BODY)" nil t) - -(autoload 'cl-the "cl-macs" "\ -At present this ignores _TYPE and is simply equivalent to FORM. - -\(fn TYPE FORM)" nil t) - -(put 'cl-the 'lisp-indent-function '1) - -(autoload 'cl-declare "cl-macs" "\ -Declare SPECS about the current function while compiling. -For instance - - (cl-declare (warn 0)) - -will turn off byte-compile warnings in the function. -See Info node `(cl)Declarations' for details. - -\(fn &rest SPECS)" nil t) - -(autoload 'cl-psetf "cl-macs" "\ -Set PLACEs to the values VALs in parallel. -This is like `setf', except that all VAL forms are evaluated (in order) -before assigning any PLACEs to the corresponding values. - -\(fn PLACE VAL PLACE VAL ...)" nil t) - -(autoload 'cl-remf "cl-macs" "\ -Remove TAG from property list PLACE. -PLACE may be a symbol, or any generalized variable allowed by `setf'. -The form returns true if TAG was found and removed, nil otherwise. - -\(fn PLACE TAG)" nil t) - -(autoload 'cl-shiftf "cl-macs" "\ -Shift left among PLACEs. -Example: (cl-shiftf A B C) sets A to B, B to C, and returns the old A. -Each PLACE may be a symbol, or any generalized variable allowed by `setf'. - -\(fn PLACE... VAL)" nil t) - -(autoload 'cl-rotatef "cl-macs" "\ -Rotate left among PLACEs. -Example: (cl-rotatef A B C) sets A to B, B to C, and C to A. It returns nil. -Each PLACE may be a symbol, or any generalized variable allowed by `setf'. - -\(fn PLACE...)" nil t) - -(autoload 'cl-letf "cl-macs" "\ -Temporarily bind to PLACEs. -This is the analogue of `let', but with generalized variables (in the -sense of `setf') for the PLACEs. Each PLACE is set to the corresponding -VALUE, then the BODY forms are executed. On exit, either normally or -because of a `throw' or error, the PLACEs are set back to their original -values. Note that this macro is *not* available in Common Lisp. -As a special case, if `(PLACE)' is used instead of `(PLACE VALUE)', -the PLACE is not modified before executing BODY. - -\(fn ((PLACE VALUE) ...) BODY...)" nil t) - -(put 'cl-letf 'lisp-indent-function '1) - -(autoload 'cl-letf* "cl-macs" "\ -Temporarily bind to PLACEs. -Like `cl-letf' but where the bindings are performed one at a time, -rather than all at the end (i.e. like `let*' rather than like `let'). - -\(fn BINDINGS &rest BODY)" nil t) - -(put 'cl-letf* 'lisp-indent-function '1) - -(autoload 'cl-callf "cl-macs" "\ -Set PLACE to (FUNC PLACE ARGS...). -FUNC should be an unquoted function name. PLACE may be a symbol, -or any generalized variable allowed by `setf'. - -\(fn FUNC PLACE &rest ARGS)" nil t) - -(put 'cl-callf 'lisp-indent-function '2) - -(autoload 'cl-callf2 "cl-macs" "\ -Set PLACE to (FUNC ARG1 PLACE ARGS...). -Like `cl-callf', but PLACE is the second argument of FUNC, not the first. - -\(fn FUNC ARG1 PLACE ARGS...)" nil t) - -(put 'cl-callf2 'lisp-indent-function '3) - -(autoload 'cl-defstruct "cl-macs" "\ -Define a struct type. -This macro defines a new data type called NAME that stores data -in SLOTs. It defines a `make-NAME' constructor, a `copy-NAME' -copier, a `NAME-p' predicate, and slot accessors named `NAME-SLOT'. -You can use the accessors to set the corresponding slots, via `setf'. - -NAME may instead take the form (NAME OPTIONS...), where each -OPTION is either a single keyword or (KEYWORD VALUE) where -KEYWORD can be one of :conc-name, :constructor, :copier, :predicate, -:type, :named, :initial-offset, :print-function, or :include. - -Each SLOT may instead take the form (SNAME SDEFAULT SOPTIONS...), where -SDEFAULT is the default value of that slot and SOPTIONS are keyword-value -pairs for that slot. -Currently, only one keyword is supported, `:read-only'. If this has a non-nil -value, that slot cannot be set via `setf'. - -\(fn NAME SLOTS...)" nil t) - -(put 'cl-defstruct 'doc-string-elt '2) - -(put 'cl-defstruct 'lisp-indent-function '1) - -(autoload 'cl-deftype "cl-macs" "\ -Define NAME as a new data type. -The type name can then be used in `cl-typecase', `cl-check-type', etc. - -\(fn NAME ARGLIST &rest BODY)" nil t) - -(put 'cl-deftype 'doc-string-elt '3) - -(autoload 'cl-typep "cl-macs" "\ -Check that OBJECT is of type TYPE. -TYPE is a Common Lisp-style type specifier. - -\(fn OBJECT TYPE)" nil nil) - -(eval-and-compile (put 'cl-typep 'compiler-macro #'cl--compiler-macro-typep)) - -(autoload 'cl-check-type "cl-macs" "\ -Verify that FORM is of type TYPE; signal an error if not. -STRING is an optional description of the desired type. - -\(fn FORM TYPE &optional STRING)" nil t) - -(autoload 'cl-assert "cl-macs" "\ -Verify that FORM returns non-nil; signal an error if not. -Second arg SHOW-ARGS means to include arguments of FORM in message. -Other args STRING and ARGS... are arguments to be passed to `error'. -They are not evaluated unless the assertion fails. If STRING is -omitted, a default message listing FORM itself is used. - -\(fn FORM &optional SHOW-ARGS STRING &rest ARGS)" nil t) - -(autoload 'cl-define-compiler-macro "cl-macs" "\ -Define a compiler-only macro. -This is like `defmacro', but macro expansion occurs only if the call to -FUNC is compiled (i.e., not interpreted). Compiler macros should be used -for optimizing the way calls to FUNC are compiled; the form returned by -BODY should do the same thing as a call to the normal function called -FUNC, though possibly more efficiently. Note that, like regular macros, -compiler macros are expanded repeatedly until no further expansions are -possible. Unlike regular macros, BODY can decide to \"punt\" and leave the -original function call alone by declaring an initial `&whole foo' parameter -and then returning foo. - -\(fn FUNC ARGS &rest BODY)" nil t) - -(autoload 'cl-compiler-macroexpand "cl-macs" "\ -Like `macroexpand', but for compiler macros. -Expands FORM repeatedly until no further expansion is possible. -Returns FORM unchanged if it has no compiler macro, or if it has a -macro that returns its `&whole' argument. - -\(fn FORM)" nil nil) - -(autoload 'cl-defsubst "cl-macs" "\ -Define NAME as a function. -Like `defun', except the function is automatically declared `inline', -ARGLIST allows full Common Lisp conventions, and BODY is implicitly -surrounded by (cl-block NAME ...). - -\(fn NAME ARGLIST [DOCSTRING] BODY...)" nil t) - -(put 'cl-defsubst 'lisp-indent-function '2) - -(autoload 'cl--compiler-macro-adjoin "cl-macs" "\ - - -\(fn FORM A LIST &rest KEYS)" nil nil) - -;;;*** - -;;;### (autoloads (cl-tree-equal cl-nsublis cl-sublis cl-nsubst-if-not -;;;;;; cl-nsubst-if cl-nsubst cl-subst-if-not cl-subst-if cl-subsetp -;;;;;; cl-nset-exclusive-or cl-set-exclusive-or cl-nset-difference -;;;;;; cl-set-difference cl-nintersection cl-intersection cl-nunion -;;;;;; cl-union cl-rassoc-if-not cl-rassoc-if cl-rassoc cl-assoc-if-not -;;;;;; cl-assoc-if cl-assoc cl--adjoin cl-member-if-not cl-member-if -;;;;;; cl-member cl-merge cl-stable-sort cl-sort cl-search cl-mismatch -;;;;;; cl-count-if-not cl-count-if cl-count cl-position-if-not cl-position-if -;;;;;; cl-position cl-find-if-not cl-find-if cl-find cl-nsubstitute-if-not -;;;;;; cl-nsubstitute-if cl-nsubstitute cl-substitute-if-not cl-substitute-if -;;;;;; cl-substitute cl-delete-duplicates cl-remove-duplicates cl-delete-if-not -;;;;;; cl-delete-if cl-delete cl-remove-if-not cl-remove-if cl-remove -;;;;;; cl-replace cl-fill cl-reduce) "cl-seq" "cl-seq.el" "51a70dea9cbc225165a50135956609aa") -;;; Generated autoloads from cl-seq.el - -(autoload 'cl-reduce "cl-seq" "\ -Reduce two-argument FUNCTION across SEQ. - -Keywords supported: :start :end :from-end :initial-value :key - -\(fn FUNCTION SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-fill "cl-seq" "\ -Fill the elements of SEQ with ITEM. - -Keywords supported: :start :end - -\(fn SEQ ITEM [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-replace "cl-seq" "\ -Replace the elements of SEQ1 with the elements of SEQ2. -SEQ1 is destructively modified, then returned. - -Keywords supported: :start1 :end1 :start2 :end2 - -\(fn SEQ1 SEQ2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-remove "cl-seq" "\ -Remove all occurrences of ITEM in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :test :test-not :key :count :start :end :from-end - -\(fn ITEM SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-remove-if "cl-seq" "\ -Remove all items satisfying PREDICATE in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :key :count :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-remove-if-not "cl-seq" "\ -Remove all items not satisfying PREDICATE in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :key :count :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-delete "cl-seq" "\ -Remove all occurrences of ITEM in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :test :test-not :key :count :start :end :from-end - -\(fn ITEM SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-delete-if "cl-seq" "\ -Remove all items satisfying PREDICATE in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :key :count :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-delete-if-not "cl-seq" "\ -Remove all items not satisfying PREDICATE in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :key :count :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-remove-duplicates "cl-seq" "\ -Return a copy of SEQ with all duplicate elements removed. - -Keywords supported: :test :test-not :key :start :end :from-end - -\(fn SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-delete-duplicates "cl-seq" "\ -Remove all duplicate elements from SEQ (destructively). - -Keywords supported: :test :test-not :key :start :end :from-end - -\(fn SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-substitute "cl-seq" "\ -Substitute NEW for OLD in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :test :test-not :key :count :start :end :from-end - -\(fn NEW OLD SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-substitute-if "cl-seq" "\ -Substitute NEW for all items satisfying PREDICATE in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :key :count :start :end :from-end - -\(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-substitute-if-not "cl-seq" "\ -Substitute NEW for all items not satisfying PREDICATE in SEQ. -This is a non-destructive function; it makes a copy of SEQ if necessary -to avoid corrupting the original SEQ. - -Keywords supported: :key :count :start :end :from-end - -\(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubstitute "cl-seq" "\ -Substitute NEW for OLD in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :test :test-not :key :count :start :end :from-end - -\(fn NEW OLD SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubstitute-if "cl-seq" "\ -Substitute NEW for all items satisfying PREDICATE in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :key :count :start :end :from-end - -\(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubstitute-if-not "cl-seq" "\ -Substitute NEW for all items not satisfying PREDICATE in SEQ. -This is a destructive function; it reuses the storage of SEQ whenever possible. - -Keywords supported: :key :count :start :end :from-end - -\(fn NEW PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-find "cl-seq" "\ -Find the first occurrence of ITEM in SEQ. -Return the matching ITEM, or nil if not found. - -Keywords supported: :test :test-not :key :start :end :from-end - -\(fn ITEM SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-find-if "cl-seq" "\ -Find the first item satisfying PREDICATE in SEQ. -Return the matching item, or nil if not found. - -Keywords supported: :key :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-find-if-not "cl-seq" "\ -Find the first item not satisfying PREDICATE in SEQ. -Return the matching item, or nil if not found. - -Keywords supported: :key :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-position "cl-seq" "\ -Find the first occurrence of ITEM in SEQ. -Return the index of the matching item, or nil if not found. - -Keywords supported: :test :test-not :key :start :end :from-end - -\(fn ITEM SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-position-if "cl-seq" "\ -Find the first item satisfying PREDICATE in SEQ. -Return the index of the matching item, or nil if not found. - -Keywords supported: :key :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-position-if-not "cl-seq" "\ -Find the first item not satisfying PREDICATE in SEQ. -Return the index of the matching item, or nil if not found. - -Keywords supported: :key :start :end :from-end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-count "cl-seq" "\ -Count the number of occurrences of ITEM in SEQ. - -Keywords supported: :test :test-not :key :start :end - -\(fn ITEM SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-count-if "cl-seq" "\ -Count the number of items satisfying PREDICATE in SEQ. - -Keywords supported: :key :start :end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-count-if-not "cl-seq" "\ -Count the number of items not satisfying PREDICATE in SEQ. - -Keywords supported: :key :start :end - -\(fn PREDICATE SEQ [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-mismatch "cl-seq" "\ -Compare SEQ1 with SEQ2, return index of first mismatching element. -Return nil if the sequences match. If one sequence is a prefix of the -other, the return value indicates the end of the shorter sequence. - -Keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end - -\(fn SEQ1 SEQ2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-search "cl-seq" "\ -Search for SEQ1 as a subsequence of SEQ2. -Return the index of the leftmost element of the first match found; -return nil if there are no matches. - -Keywords supported: :test :test-not :key :start1 :end1 :start2 :end2 :from-end - -\(fn SEQ1 SEQ2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-sort "cl-seq" "\ -Sort the argument SEQ according to PREDICATE. -This is a destructive function; it reuses the storage of SEQ if possible. - -Keywords supported: :key - -\(fn SEQ PREDICATE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-stable-sort "cl-seq" "\ -Sort the argument SEQ stably according to PREDICATE. -This is a destructive function; it reuses the storage of SEQ if possible. - -Keywords supported: :key - -\(fn SEQ PREDICATE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-merge "cl-seq" "\ -Destructively merge the two sequences to produce a new sequence. -TYPE is the sequence type to return, SEQ1 and SEQ2 are the two argument -sequences, and PREDICATE is a `less-than' predicate on the elements. - -Keywords supported: :key - -\(fn TYPE SEQ1 SEQ2 PREDICATE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-member "cl-seq" "\ -Find the first occurrence of ITEM in LIST. -Return the sublist of LIST whose car is ITEM. - -Keywords supported: :test :test-not :key - -\(fn ITEM LIST [KEYWORD VALUE]...)" nil nil) - -(eval-and-compile (put 'cl-member 'compiler-macro #'cl--compiler-macro-member)) - -(autoload 'cl-member-if "cl-seq" "\ -Find the first item satisfying PREDICATE in LIST. -Return the sublist of LIST whose car matches. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-member-if-not "cl-seq" "\ -Find the first item not satisfying PREDICATE in LIST. -Return the sublist of LIST whose car matches. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl--adjoin "cl-seq" "\ - - -\(fn CL-ITEM CL-LIST &rest CL-KEYS)" nil nil) - -(autoload 'cl-assoc "cl-seq" "\ -Find the first item whose car matches ITEM in LIST. - -Keywords supported: :test :test-not :key - -\(fn ITEM LIST [KEYWORD VALUE]...)" nil nil) - -(eval-and-compile (put 'cl-assoc 'compiler-macro #'cl--compiler-macro-assoc)) - -(autoload 'cl-assoc-if "cl-seq" "\ -Find the first item whose car satisfies PREDICATE in LIST. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-assoc-if-not "cl-seq" "\ -Find the first item whose car does not satisfy PREDICATE in LIST. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-rassoc "cl-seq" "\ -Find the first item whose cdr matches ITEM in LIST. - -Keywords supported: :test :test-not :key - -\(fn ITEM LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-rassoc-if "cl-seq" "\ -Find the first item whose cdr satisfies PREDICATE in LIST. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-rassoc-if-not "cl-seq" "\ -Find the first item whose cdr does not satisfy PREDICATE in LIST. - -Keywords supported: :key - -\(fn PREDICATE LIST [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-union "cl-seq" "\ -Combine LIST1 and LIST2 using a set-union operation. -The resulting list contains all items that appear in either LIST1 or LIST2. -This is a non-destructive function; it makes a copy of the data if necessary -to avoid corrupting the original LIST1 and LIST2. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nunion "cl-seq" "\ -Combine LIST1 and LIST2 using a set-union operation. -The resulting list contains all items that appear in either LIST1 or LIST2. -This is a destructive function; it reuses the storage of LIST1 and LIST2 -whenever possible. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-intersection "cl-seq" "\ -Combine LIST1 and LIST2 using a set-intersection operation. -The resulting list contains all items that appear in both LIST1 and LIST2. -This is a non-destructive function; it makes a copy of the data if necessary -to avoid corrupting the original LIST1 and LIST2. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nintersection "cl-seq" "\ -Combine LIST1 and LIST2 using a set-intersection operation. -The resulting list contains all items that appear in both LIST1 and LIST2. -This is a destructive function; it reuses the storage of LIST1 and LIST2 -whenever possible. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-set-difference "cl-seq" "\ -Combine LIST1 and LIST2 using a set-difference operation. -The resulting list contains all items that appear in LIST1 but not LIST2. -This is a non-destructive function; it makes a copy of the data if necessary -to avoid corrupting the original LIST1 and LIST2. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nset-difference "cl-seq" "\ -Combine LIST1 and LIST2 using a set-difference operation. -The resulting list contains all items that appear in LIST1 but not LIST2. -This is a destructive function; it reuses the storage of LIST1 and LIST2 -whenever possible. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-set-exclusive-or "cl-seq" "\ -Combine LIST1 and LIST2 using a set-exclusive-or operation. -The resulting list contains all items appearing in exactly one of LIST1, LIST2. -This is a non-destructive function; it makes a copy of the data if necessary -to avoid corrupting the original LIST1 and LIST2. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nset-exclusive-or "cl-seq" "\ -Combine LIST1 and LIST2 using a set-exclusive-or operation. -The resulting list contains all items appearing in exactly one of LIST1, LIST2. -This is a destructive function; it reuses the storage of LIST1 and LIST2 -whenever possible. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-subsetp "cl-seq" "\ -Return true if LIST1 is a subset of LIST2. -I.e., if every element of LIST1 also appears in LIST2. - -Keywords supported: :test :test-not :key - -\(fn LIST1 LIST2 [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-subst-if "cl-seq" "\ -Substitute NEW for elements matching PREDICATE in TREE (non-destructively). -Return a copy of TREE with all matching elements replaced by NEW. - -Keywords supported: :key - -\(fn NEW PREDICATE TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-subst-if-not "cl-seq" "\ -Substitute NEW for elts not matching PREDICATE in TREE (non-destructively). -Return a copy of TREE with all non-matching elements replaced by NEW. - -Keywords supported: :key - -\(fn NEW PREDICATE TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubst "cl-seq" "\ -Substitute NEW for OLD everywhere in TREE (destructively). -Any element of TREE which is `eql' to OLD is changed to NEW (via a call -to `setcar'). - -Keywords supported: :test :test-not :key - -\(fn NEW OLD TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubst-if "cl-seq" "\ -Substitute NEW for elements matching PREDICATE in TREE (destructively). -Any element of TREE which matches is changed to NEW (via a call to `setcar'). - -Keywords supported: :key - -\(fn NEW PREDICATE TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsubst-if-not "cl-seq" "\ -Substitute NEW for elements not matching PREDICATE in TREE (destructively). -Any element of TREE which matches is changed to NEW (via a call to `setcar'). - -Keywords supported: :key - -\(fn NEW PREDICATE TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-sublis "cl-seq" "\ -Perform substitutions indicated by ALIST in TREE (non-destructively). -Return a copy of TREE with all matching elements replaced. - -Keywords supported: :test :test-not :key - -\(fn ALIST TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-nsublis "cl-seq" "\ -Perform substitutions indicated by ALIST in TREE (destructively). -Any matching element of TREE is changed via a call to `setcar'. - -Keywords supported: :test :test-not :key - -\(fn ALIST TREE [KEYWORD VALUE]...)" nil nil) - -(autoload 'cl-tree-equal "cl-seq" "\ -Return t if trees TREE1 and TREE2 have `eql' leaves. -Atoms are compared by `eql'; cons cells are compared recursively. - -Keywords supported: :test :test-not :key - -\(fn TREE1 TREE2 [KEYWORD VALUE]...)" nil nil) - -;;;*** - -;; Local Variables: -;; version-control: never -;; no-byte-compile: t -;; no-update-autoloads: t -;; coding: utf-8 -;; End: -;;; cl-loaddefs.el ends here diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el index 34957d86796..3cf744f1245 100644 --- a/lisp/emacs-lisp/cl-macs.el +++ b/lisp/emacs-lisp/cl-macs.el @@ -3,7 +3,7 @@ ;; Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. ;; Author: Dave Gillespie <daveg@synaptics.com> -;; Version: 2.02 +;; Old-Version: 2.02 ;; Keywords: extensions ;; Package: emacs @@ -2739,9 +2739,17 @@ surrounded by (cl-block NAME ...). (setq body (cond ((null substs) body) ((null (cdr substs)) (cl-subst (cdar substs) (caar substs) body)) - (t (cl-sublis substs body)))) + (t (cl--sublis substs body)))) (if lets `(let ,lets ,body) body)))) +(defun cl--sublis (alist tree) + "Perform substitutions indicated by ALIST in TREE (non-destructively)." + (let ((x (assq tree alist))) + (cond + (x (cdr x)) + ((consp tree) + (cons (cl--sublis alist (car tree)) (cl--sublis alist (cdr tree)))) + (t tree)))) ;; Compile-time optimizations for some functions defined in this package. diff --git a/lisp/emacs-lisp/cl-seq.el b/lisp/emacs-lisp/cl-seq.el index fbf68f62b4a..6b5b329e33f 100644 --- a/lisp/emacs-lisp/cl-seq.el +++ b/lisp/emacs-lisp/cl-seq.el @@ -3,7 +3,7 @@ ;; Copyright (C) 1993, 2001-2013 Free Software Foundation, Inc. ;; Author: Dave Gillespie <daveg@synaptics.com> -;; Version: 2.02 +;; Old-Version: 2.02 ;; Keywords: extensions ;; Package: emacs diff --git a/lisp/emacs-lisp/eieio-custom.el b/lisp/emacs-lisp/eieio-custom.el index f9917bddd42..aff07b29edf 100644 --- a/lisp/emacs-lisp/eieio-custom.el +++ b/lisp/emacs-lisp/eieio-custom.el @@ -4,7 +4,8 @@ ;; Inc. ;; Author: Eric M. Ludlam <zappo@gnu.org> -;; Version: 0.2 +;; Old-Version: 0.2 (using "Version:" made Emacs think this is package +;; eieio-0.2). ;; Keywords: OO, lisp ;; Package: eieio diff --git a/lisp/emacs-lisp/eieio.el b/lisp/emacs-lisp/eieio.el index 3cdf1f078bd..fc5da3198f9 100644 --- a/lisp/emacs-lisp/eieio.el +++ b/lisp/emacs-lisp/eieio.el @@ -115,7 +115,12 @@ Options in CLOS not supported in EIEIO: Due to the way class options are set up, you can add any tags you wish, and reference them using the function `class-option'." - `(eieio-defclass ',name ',superclass ',slots ',options-and-doc)) + ;; This is eval-and-compile only to silence spurious compiler warnings + ;; about functions and variables not known to be defined. + ;; When eieio-defclass code is merged here and this becomes + ;; transparent to the compiler, the eval-and-compile can be removed. + `(eval-and-compile + (eieio-defclass ',name ',superclass ',slots ',options-and-doc))) ;;; CLOS style implementation of object creators. diff --git a/lisp/emacs-lisp/generic.el b/lisp/emacs-lisp/generic.el index cb86a554335..3eb64f9f7f0 100644 --- a/lisp/emacs-lisp/generic.el +++ b/lisp/emacs-lisp/generic.el @@ -44,11 +44,8 @@ ;; end at the end of the line.) Emacs does not support comment ;; strings of more than two characters in length. ;; -;; * List of keywords to font-lock. Each keyword should be a string. -;; If you have additional keywords which should be highlighted in a -;; face different from `font-lock-keyword-face', you can use the -;; convenience function `generic-make-keywords-list' (which see), -;; and add the result to the following list: +;; * List of keywords to font-lock in `font-lock-keyword-face'. +;; Each keyword should be a string. ;; ;; * Additional expressions to font-lock. This should be a list of ;; expressions, each of which should be of the same form as those in diff --git a/lisp/emacs-lisp/lisp-mode.el b/lisp/emacs-lisp/lisp-mode.el index cbd8854e7d6..af30deca4cc 100644 --- a/lisp/emacs-lisp/lisp-mode.el +++ b/lisp/emacs-lisp/lisp-mode.el @@ -1,4 +1,4 @@ -;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands +;;; lisp-mode.el --- Lisp mode, and its idiosyncratic commands -*- coding: utf-8 -*- ;; Copyright (C) 1985-1986, 1999-2013 Free Software Foundation, Inc. @@ -231,7 +231,7 @@ font-lock keywords will not be case sensitive." (font-lock-mark-block-function . mark-defun) (font-lock-syntactic-face-function . lisp-font-lock-syntactic-face-function))) - (prog-prettify-install lisp--prettify-symbols-alist)) + (setq-local prettify-symbols-alist lisp--prettify-symbols-alist)) (defun lisp-outline-level () "Lisp mode `outline-level' function." diff --git a/lisp/emacs-lisp/lisp.el b/lisp/emacs-lisp/lisp.el index a31bef2391d..b37a811b8d5 100644 --- a/lisp/emacs-lisp/lisp.el +++ b/lisp/emacs-lisp/lisp.el @@ -59,7 +59,8 @@ Should take the same arguments and behave similarly to `forward-sexp'.") "Move forward across one balanced expression (sexp). With ARG, do it that many times. Negative arg -N means move backward across N balanced expressions. -This command assumes point is not in a string or comment." +This command assumes point is not in a string or comment. +Calls `forward-sexp-function' to do the work, if that is non-nil." (interactive "^p") (or arg (setq arg 1)) (if forward-sexp-function @@ -71,7 +72,8 @@ This command assumes point is not in a string or comment." "Move backward across one balanced expression (sexp). With ARG, do it that many times. Negative arg -N means move forward across N balanced expressions. -This command assumes point is not in a string or comment." +This command assumes point is not in a string or comment. +Uses `forward-sexp' to do the work." (interactive "^p") (or arg (setq arg 1)) (forward-sexp (- arg))) diff --git a/lisp/emacs-lisp/map-ynp.el b/lisp/emacs-lisp/map-ynp.el index 13202a9ce4d..1919d47687b 100644 --- a/lisp/emacs-lisp/map-ynp.el +++ b/lisp/emacs-lisp/map-ynp.el @@ -1,4 +1,4 @@ -;;; map-ynp.el --- general-purpose boolean question-asker +;;; map-ynp.el --- general-purpose boolean question-asker -*- lexical-binding:t -*- ;; Copyright (C) 1991-1995, 2000-2013 Free Software Foundation, Inc. @@ -79,7 +79,7 @@ are meaningful here. Returns the number of actions taken." (let* ((actions 0) - user-keys mouse-event map prompt char elt tail def + user-keys mouse-event map prompt char elt def ;; Non-nil means we should use mouse menus to ask. use-menus delayed-switch-frame @@ -89,13 +89,15 @@ Returns the number of actions taken." (next (if (functionp list) (lambda () (setq elt (funcall list))) (lambda () (when list - (setq elt (pop list)) - t))))) + (setq elt (pop list)) + t)))) + (try-again (lambda () + (let ((x next)) + (setq next (lambda () (setq next x) elt)))))) (if (and (listp last-nonmenu-event) use-dialog-box) ;; Make a list describing a dialog box. - (let ((object (if help (capitalize (nth 0 help)))) - (objects (if help (capitalize (nth 1 help)))) + (let ((objects (if help (capitalize (nth 1 help)))) (action (if help (capitalize (nth 2 help))))) (setq map `(("Yes" . act) ("No" . skip) ,@(mapcar (lambda (elt) @@ -129,8 +131,8 @@ Returns the number of actions taken." (unwind-protect (progn (if (stringp prompter) - (setq prompter `(lambda (object) - (format ,prompter object)))) + (setq prompter (lambda (object) + (format prompter object)))) (while (funcall next) (setq prompt (funcall prompter elt)) (cond ((stringp prompt) @@ -176,9 +178,7 @@ Returns the number of actions taken." next (lambda () nil))) ((eq def 'quit) (setq quit-flag t) - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) ((eq def 'automatic) ;; Act on this and all following objects. (if (funcall prompter elt) @@ -219,40 +219,30 @@ the current %s and exit." (with-current-buffer standard-output (help-mode))) - (setq next `(lambda () - (setq next ',next) - ',elt))) - ((and (symbolp def) (commandp def)) - (call-interactively def) - ;; Regurgitated; try again. - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) + ((and (symbolp def) (commandp def)) + (call-interactively def) + ;; Regurgitated; try again. + (funcall try-again)) ((vectorp def) ;; A user-defined key. (if (funcall (aref def 0) elt) ;Call its function. ;; The function has eaten this object. (setq actions (1+ actions)) ;; Regurgitated; try again. - (setq next `(lambda () - (setq next ',next) - ',elt)))) + (funcall try-again))) ((and (consp char) (eq (car char) 'switch-frame)) ;; switch-frame event. Put it off until we're done. (setq delayed-switch-frame char) - (setq next `(lambda () - (setq next ',next) - ',elt))) + (funcall try-again)) (t ;; Random char. (message "Type %s for help." (key-description (vector help-char))) (beep) (sit-for 1) - (setq next `(lambda () - (setq next ',next) - ',elt))))) + (funcall try-again)))) (prompt (funcall actor elt) (setq actions (1+ actions)))))) diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index c08d671e7eb..8b149aad7bb 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -313,8 +313,7 @@ of the piece of advice." (when (get symbol 'advice--saved-rewrite) (put symbol 'advice--saved-rewrite nil)) (setq newdef (advice--normalize symbol newdef)) - (let* ((olddef (advice--strip-macro - (if (fboundp symbol) (symbol-function symbol)))) + (let* ((olddef (advice--strip-macro (symbol-function symbol))) (oldadv (cond ((null (get symbol 'advice--pending)) @@ -324,15 +323,18 @@ of the piece of advice." symbol) nil))) ((or (not olddef) (autoloadp olddef)) - (prog1 (get symbol 'advice--pending) - (put symbol 'advice--pending nil))) + (get symbol 'advice--pending)) (t (message "Dropping left-over advice--pending for %s" symbol) - (put symbol 'advice--pending nil) olddef)))) - (let* ((snewdef (advice--strip-macro newdef)) - (snewadv (advice--subst-main oldadv snewdef))) - (funcall (or fsetfun #'fset) symbol - (if (eq snewdef newdef) snewadv (cons 'macro snewadv)))))) + (if (and newdef (not (autoloadp newdef))) + (let* ((snewdef (advice--strip-macro newdef)) + (snewadv (advice--subst-main oldadv snewdef))) + (put symbol 'advice--pending nil) + (funcall (or fsetfun #'fset) symbol + (if (eq snewdef newdef) snewadv (cons 'macro snewadv)))) + (unless (eq oldadv (get symbol 'advice--pending)) + (put symbol 'advice--pending (advice--subst-main oldadv nil))) + (funcall (or fsetfun #'fset) symbol newdef)))) ;;;###autoload @@ -345,7 +347,7 @@ is defined as a macro, alias, command, ..." ;; - change all defadvice in lisp/**/*.el. ;; - rewrite advice.el on top of this. ;; - obsolete advice.el. - (let* ((f (and (fboundp symbol) (symbol-function symbol))) + (let* ((f (symbol-function symbol)) (nf (advice--normalize symbol f))) (unless (eq f nf) ;; Most importantly, if nf == nil! (fset symbol nf)) @@ -370,37 +372,34 @@ is defined as a macro, alias, command, ..." ;;;###autoload (defun advice-remove (symbol function) "Like `remove-function' but for the function named SYMBOL. -Contrary to `remove-function', this will work also when SYMBOL is a macro -and it will not signal an error if SYMBOL is not `fboundp'. +Contrary to `remove-function', this also works when SYMBOL is a macro +or an autoload and it preserves `fboundp'. Instead of the actual function to remove, FUNCTION can also be the `name' of the piece of advice." - (when (fboundp symbol) - (let ((f (symbol-function symbol))) - ;; Can't use the `if' place here, because the body is too large, - ;; resulting in use of code that only works with lexical-scoping. - (remove-function (if (eq (car-safe f) 'macro) - (cdr f) - (symbol-function symbol)) - function) - (unless (advice--p - (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol))) - ;; Not advised any more. - (remove-function (get symbol 'defalias-fset-function) - #'advice--defalias-fset) - (if (eq (symbol-function symbol) - (cdr (get symbol 'advice--saved-rewrite))) - (fset symbol (car (get symbol 'advice--saved-rewrite)))))) - nil)) - -;; (defun advice-mapc (fun symbol) -;; "Apply FUN to every function added as advice to SYMBOL. -;; FUN is called with a two arguments: the function that was added, and the -;; properties alist that was specified when it was added." -;; (let ((def (or (get symbol 'advice--pending) -;; (if (fboundp symbol) (symbol-function symbol))))) -;; (while (advice--p def) -;; (funcall fun (advice--car def) (advice--props def)) -;; (setq def (advice--cdr def))))) + (let ((f (symbol-function symbol))) + ;; Can't use the `if' place here, because the body is too large, + ;; resulting in use of code that only works with lexical-scoping. + (remove-function (if (eq (car-safe f) 'macro) + (cdr f) + (symbol-function symbol)) + function) + (unless (advice--p + (if (eq (car-safe f) 'macro) (cdr f) (symbol-function symbol))) + ;; Not advised any more. + (remove-function (get symbol 'defalias-fset-function) + #'advice--defalias-fset) + (if (eq (symbol-function symbol) + (cdr (get symbol 'advice--saved-rewrite))) + (fset symbol (car (get symbol 'advice--saved-rewrite)))))) + nil) + +(defun advice-mapc (fun def) + "Apply FUN to every advice function in DEF. +FUN is called with a two arguments: the function that was added, and the +properties alist that was specified when it was added." + (while (advice--p def) + (funcall fun (advice--car def) (advice--props def)) + (setq def (advice--cdr def)))) ;;;###autoload (defun advice-member-p (advice function-name) @@ -410,8 +409,7 @@ of the piece of advice." (advice--member-p advice advice (or (get function-name 'advice--pending) (advice--strip-macro - (if (fboundp function-name) - (symbol-function function-name)))))) + (symbol-function function-name))))) ;; When code is advised, called-interactively-p needs to be taught to skip ;; the advising frames. diff --git a/lisp/emacs-lisp/package-x.el b/lisp/emacs-lisp/package-x.el index 17919d9bbeb..76d7565d64b 100644 --- a/lisp/emacs-lisp/package-x.el +++ b/lisp/emacs-lisp/package-x.el @@ -4,7 +4,6 @@ ;; Author: Tom Tromey <tromey@redhat.com> ;; Created: 10 Mar 2007 -;; Version: 0.9 ;; Keywords: tools ;; Package: package @@ -205,12 +204,12 @@ if it exists." package--default-summary) (read-string "Description of package: ") (package-desc-summary pkg-desc))) - (pkg-version (package-desc-version pkg-desc)) + (split-version (package-desc-version pkg-desc)) (commentary (pcase file-type (`single (lm-commentary)) (`tar nil))) ;; FIXME: Get it from the README file. - (split-version (version-to-list pkg-version)) + (pkg-version (package-version-join split-version)) (pkg-buffer (current-buffer))) ;; Get archive-contents from ARCHIVE-URL if it's non-nil, or @@ -224,7 +223,7 @@ if it exists." (let ((elt (assq pkg-name (cdr contents)))) (if elt (if (version-list-<= split-version - (package-desc-vers (cdr elt))) + (package--ac-desc-version (cdr elt))) (error "New package has smaller version: %s" pkg-version) (setcdr elt new-desc)) (setq contents (cons (car contents) @@ -291,10 +290,11 @@ If `package-archive-upload-base' does not specify a valid upload destination, prompt for one." (interactive "fPackage file name: ") (with-temp-buffer - (insert-file-contents-literally file) + (insert-file-contents file) (let ((pkg-desc (cond - ((string-match "\\.tar\\'" file) (package-tar-file-info file)) + ((string-match "\\.tar\\'" file) + (tar-mode) (package-tar-file-info)) ((string-match "\\.el\\'" file) (package-buffer-info)) (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el index d5176abded0..32339249085 100644 --- a/lisp/emacs-lisp/package.el +++ b/lisp/emacs-lisp/package.el @@ -1,8 +1,9 @@ -;;; package.el --- Simple package system for Emacs +;;; package.el --- Simple package system for Emacs -*- lexical-binding:t -*- ;; Copyright (C) 2007-2013 Free Software Foundation, Inc. ;; Author: Tom Tromey <tromey@redhat.com> +;; Daniel Hackney <dan@haxney.org> ;; Created: 10 Mar 2007 ;; Version: 1.0.1 ;; Keywords: tools @@ -140,7 +141,6 @@ ;; installing it ;; - Interface with desktop.el so that restarting after an install ;; works properly -;; - Implement M-x package-upgrade, to upgrade any/all existing packages ;; - Use hierarchical layout. PKG/etc PKG/lisp PKG/info ;; ... except maybe lisp? ;; - It may be nice to have a macro that expands to the package's @@ -159,14 +159,7 @@ ;; - Allow optional package dependencies ;; then if we require 'bbdb', bbdb-specific lisp in lisp/bbdb ;; and just don't compile to add to load path ...? -;; - Have a list of archive URLs? [ maybe there's no point ] -;; - David Kastrup pointed out on the xemacs list that for GPL it -;; is friendlier to ship the source tree. We could "support" that -;; by just having a "src" subdir in the package. This isn't ideal -;; but it probably is not worth trying to support random source -;; tree layouts, build schemes, etc. ;; - Our treatment of the info path is somewhat bogus -;; - perhaps have an "unstable" tree in ELPA as well as a stable one ;;; Code: @@ -200,8 +193,7 @@ versions of all packages not specified by other elements. For an element (NAME VERSION), NAME is a package name (a symbol). VERSION should be t, a string, or nil. -If VERSION is t, all versions are loaded, though obsolete ones - will be put in `package-obsolete-alist' and not activated. +If VERSION is t, the most recent version is activated. If VERSION is a string, only that version is ever loaded. Any other version, even if newer, is silently ignored. Hence, the package is \"held\" at that version. @@ -242,7 +234,7 @@ a package can run arbitrary code." Each element has the form (SYM . ID). SYM is a package, as a symbol. - ID is an archive name, as a string. This should correspond to an + ID is an archive name. This should correspond to an entry in `package-archives'. If the archive of name ID does not contain the package SYM, no @@ -258,14 +250,11 @@ package unavailable." "Version number of the package archive understood by this file. Lower version numbers than this will probably be understood as well.") -(defconst package-el-version "1.0.1" - "Version of package.el.") - ;; We don't prime the cache since it tends to get out of date. (defvar package-archive-contents nil "Cache of the contents of the Emacs Lisp Package Archive. This is an alist mapping package names (symbols) to -`package--desc' structures.") +non-empty lists of `package-desc' structures.") (put 'package-archive-contents 'risky-local-variable t) (defcustom package-user-dir (locate-user-emacs-file "elpa") @@ -318,31 +307,46 @@ contrast, `package-user-dir' contains packages for personal use." (nth 1 requirements) requirements)))))) "Structure containing information about an individual package. - Slots: -`name' Name of the package, as a symbol. +`name' Name of the package, as a symbol. `version' Version of the package, as a version list. `summary' Short description of the package, typically taken from -the first line of the file. + the first line of the file. -`reqs' Requirements of the package. A list of (PACKAGE -VERSION-LIST) naming the dependent package and the minimum -required version. +`reqs' Requirements of the package. A list of (PACKAGE + VERSION-LIST) naming the dependent package and the minimum + required version. -`kind' The distribution format of the package. Currently, it is -either `single' or `tar'. +`kind' The distribution format of the package. Currently, it is + either `single' or `tar'. `archive' The name of the archive (as a string) whence this -package came." + package came. + +`dir' The directory where the package is installed (if installed), + `builtin' if it is built-in, or nil otherwise." name version (summary package--default-summary) reqs kind - archive) + archive + dir) + +;; Pseudo fields. +(defun package-desc-full-name (pkg-desc) + (format "%s-%s" + (package-desc-name pkg-desc) + (package-version-join (package-desc-version pkg-desc)))) + +(defun package-desc-suffix (pkg-desc) + (pcase (package-desc-kind pkg-desc) + (`single ".el") + (`tar ".tar") + (kind (error "Unknown package kind: %s" kind)))) ;; Package descriptor format used in finder-inf.el and package--builtins. (cl-defstruct (package--bi-desc @@ -352,8 +356,6 @@ package came." reqs summary) -;; The value is precomputed in finder-inf.el, but don't load that -;; until it's needed (i.e. when `package-initialize' is called). (defvar package--builtins nil "Alist of built-in packages. The actual value is initialized by loading the library @@ -366,8 +368,9 @@ name (a symbol) and DESC is a `package--bi-desc' structure.") (defvar package-alist nil "Alist of all packages available for activation. -Each element has the form (PKG . DESC), where PKG is a package -name (a symbol) and DESC is a `package-desc' structure. +Each element has the form (PKG . DESCS), where PKG is a package +name (a symbol) and DESCS is a non-empty list of `package-desc' structure, +sorted by decreasing versions. This variable is set automatically by `package-load-descriptor', called via `package-initialize'. To change which packages are @@ -375,18 +378,10 @@ loaded and/or activated, customize `package-load-list'.") (put 'package-alist 'risky-local-variable t) (defvar package-activated-list nil + ;; FIXME: This should implicitly include all builtin packages. "List of the names of currently activated packages.") (put 'package-activated-list 'risky-local-variable t) -(defvar package-obsolete-alist nil - "Representation of obsolete packages. -Like `package-alist', but maps package name to a second alist. -The inner alist is keyed by version. - -Each element of the list is (NAME . VERSION-ALIST), where each -entry in VERSION-ALIST is (VERSION-LIST . PACKAGE-DESC).") -(put 'package-obsolete-alist 'risky-local-variable t) - (defun package-version-join (vlist) "Return the version string corresponding to the list VLIST. This is, approximately, the inverse of `version-to-list'. @@ -416,23 +411,18 @@ This is, approximately, the inverse of `version-to-list'. (pop str-list)) (apply 'concat (nreverse str-list))))) -(defun package-strip-version (dirname) - "Strip the version from a combined package name and version. -E.g., if given \"quux-23.0\", will return \"quux\"" - (if (string-match (concat "\\`" package-subdirectory-regexp "\\'") dirname) - (match-string 1 dirname))) - -(defun package-load-descriptor (dir package) - "Load the description file in directory DIR for package PACKAGE. -Here, PACKAGE is a string of the form NAME-VERSION, where NAME is -the package name and VERSION is its version." - (let* ((pkg-dir (expand-file-name package dir)) - (pkg-file (expand-file-name - (concat (package-strip-version package) "-pkg") - pkg-dir))) - (when (and (file-directory-p pkg-dir) - (file-exists-p (concat pkg-file ".el"))) - (load pkg-file nil t)))) +(defun package-load-descriptor (pkg-dir) + "Load the description file in directory PKG-DIR." + (let ((pkg-file (expand-file-name (package--description-file pkg-dir) + pkg-dir))) + (when (file-exists-p pkg-file) + (with-temp-buffer + (insert-file-contents pkg-file) + (goto-char (point-min)) + (let ((pkg-desc (package-process-define-package + (read (current-buffer)) pkg-file))) + (setf (package-desc-dir pkg-desc) pkg-dir) + pkg-desc))))) (defun package-load-all-descriptors () "Load descriptors for installed Emacs Lisp packages. @@ -442,66 +432,35 @@ controls which package subdirectories may be loaded. In each valid package subdirectory, this function loads the description file containing a call to `define-package', which -updates `package-alist' and `package-obsolete-alist'." - (let ((regexp (concat "\\`" package-subdirectory-regexp "\\'"))) - (dolist (dir (cons package-user-dir package-directory-list)) - (when (file-directory-p dir) - (dolist (subdir (directory-files dir)) - (when (string-match regexp subdir) - (package-maybe-load-descriptor (match-string 1 subdir) - (match-string 2 subdir) - dir))))))) - -(defun package-maybe-load-descriptor (name version dir) - "Maybe load a specific package from directory DIR. -NAME and VERSION are the package's name and version strings. -This function checks `package-load-list', before actually loading -the package by calling `package-load-descriptor'." - (let ((force (assq (intern name) package-load-list)) - (subdir (concat name "-" version))) - (and (file-directory-p (expand-file-name subdir dir)) - ;; Check `package-load-list': - (cond ((null force) - (memq 'all package-load-list)) - ((null (setq force (cadr force))) - nil) ; disabled - ((eq force t) - t) - ((stringp force) ; held - (version-list-= (version-to-list version) - (version-to-list force))) - (t - (error "Invalid element in `package-load-list'"))) - ;; Actually load the descriptor: - (package-load-descriptor dir subdir)))) - -(define-obsolete-function-alias 'package-desc-vers 'package-desc-version "24.4") - -(define-obsolete-function-alias 'package-desc-doc 'package-desc-summary "24.4") - - -(defun package--dir (name version) - ;; FIXME: Keep this as a field in the package-desc. - "Return the directory where a package is installed, or nil if none. -NAME is a symbol and VERSION is a string." - (let* ((subdir (format "%s-%s" name version)) - (dir-list (cons package-user-dir package-directory-list)) - pkg-dir) - (while dir-list - (let ((subdir-full (expand-file-name subdir (car dir-list)))) - (if (file-directory-p subdir-full) - (setq pkg-dir subdir-full - dir-list nil) - (setq dir-list (cdr dir-list))))) - pkg-dir)) +updates `package-alist'." + (dolist (dir (cons package-user-dir package-directory-list)) + (when (file-directory-p dir) + (dolist (subdir (directory-files dir)) + (let ((pkg-dir (expand-file-name subdir dir))) + (when (file-directory-p pkg-dir) + (package-load-descriptor pkg-dir))))))) + +(defun package-disabled-p (pkg-name version) + "Return whether PKG-NAME at VERSION can be activated. +The decision is made according to `package-load-list'. +Return nil if the package can be activated. +Return t if the package is completely disabled. +Return the max version (as a string) if the package is held at a lower version." + (let ((force (assq pkg-name package-load-list))) + (cond ((null force) (not (memq 'all package-load-list))) + ((null (setq force (cadr force))) t) ; disabled + ((eq force t) nil) + ((stringp force) ; held + (unless (version-list-= version (version-to-list force)) + force)) + (t (error "Invalid element in `package-load-list'"))))) (defun package-activate-1 (pkg-desc) (let* ((name (package-desc-name pkg-desc)) - (version-str (package-version-join (package-desc-version pkg-desc))) - (pkg-dir (package--dir name version-str))) + (pkg-dir (package-desc-dir pkg-desc))) (unless pkg-dir - (error "Internal error: unable to find directory for `%s-%s'" - name version-str)) + (error "Internal error: unable to find directory for `%s'" + (package-desc-full-name pkg-desc))) ;; Add info node. (when (file-exists-p (expand-file-name "dir" pkg-dir)) ;; FIXME: not the friendliest, but simple. @@ -519,47 +478,51 @@ NAME is a symbol and VERSION is a string." "Return true if PACKAGE is built-in to Emacs. Optional arg MIN-VERSION, if non-nil, should be a version list specifying the minimum acceptable version." - (require 'finder-inf nil t) ; For `package--builtins'. - (if (eq package 'emacs) - (version-list-<= min-version (version-to-list emacs-version)) - (let ((elt (assq package package--builtins))) - (and elt (version-list-<= min-version - (package--bi-desc-version (cdr elt))))))) + (let ((bi (assq package package--builtin-versions))) + (cond + (bi (version-list-<= min-version (cdr bi))) + (min-version nil) + (t + (require 'finder-inf nil t) ; For `package--builtins'. + (assq package package--builtins))))) (defun package--from-builtin (bi-desc) (package-desc-create :name (pop bi-desc) :version (package--bi-desc-version bi-desc) - :summary (package--bi-desc-summary bi-desc))) + :summary (package--bi-desc-summary bi-desc) + :dir 'builtin)) ;; This function goes ahead and activates a newer version of a package ;; if an older one was already activated. This is not ideal; we'd at ;; least need to check to see if the package has actually been loaded, ;; and not merely activated. -(defun package-activate (package min-version) - "Activate package PACKAGE, of version MIN-VERSION or newer. -MIN-VERSION should be a version list. -If PACKAGE has any dependencies, recursively activate them. -Return nil if the package could not be activated." - (let ((pkg-vec (cdr (assq package package-alist))) - available-version found) +(defun package-activate (package &optional force) + "Activate package PACKAGE. +If FORCE is true, (re-)activate it if it's already activated." + (let ((pkg-descs (cdr (assq package package-alist)))) ;; Check if PACKAGE is available in `package-alist'. - (when pkg-vec - (setq available-version (package-desc-version pkg-vec) - found (version-list-<= min-version available-version))) + (while + (when pkg-descs + (let ((available-version (package-desc-version (car pkg-descs)))) + (or (package-disabled-p package available-version) + ;; Prefer a builtin package. + (package-built-in-p package available-version)))) + (setq pkg-descs (cdr pkg-descs))) (cond ;; If no such package is found, maybe it's built-in. - ((null found) - (package-built-in-p package min-version)) + ((null pkg-descs) + (package-built-in-p package)) ;; If the package is already activated, just return t. - ((memq package package-activated-list) + ((and (memq package package-activated-list) (not force)) t) ;; Otherwise, proceed with activation. (t - (let ((fail (catch 'dep-failure - ;; Activate its dependencies recursively. - (dolist (req (package-desc-reqs pkg-vec)) - (unless (package-activate (car req) (cadr req)) - (throw 'dep-failure req)))))) + (let* ((pkg-vec (car pkg-descs)) + (fail (catch 'dep-failure + ;; Activate its dependencies recursively. + (dolist (req (package-desc-reqs pkg-vec)) + (unless (package-activate (car req) (cadr req)) + (throw 'dep-failure req)))))) (if fail (warn "Unable to activate package `%s'. Required package `%s-%s' is unavailable" @@ -567,23 +530,9 @@ Required package `%s-%s' is unavailable" ;; If all goes well, activate the package itself. (package-activate-1 pkg-vec))))))) -(defun package-mark-obsolete (package pkg-vec) - "Put package on the obsolete list, if not already there." - (let ((elt (assq package package-obsolete-alist))) - (if elt - ;; If this obsolete version does not exist in the list, update - ;; it the list. - (unless (assoc (package-desc-version pkg-vec) (cdr elt)) - (setcdr elt (cons (cons (package-desc-version pkg-vec) pkg-vec) - (cdr elt)))) - ;; Make a new association. - (push (cons package (list (cons (package-desc-version pkg-vec) - pkg-vec))) - package-obsolete-alist)))) - -(defun define-package (name-string version-string - &optional docstring requirements - &rest _extra-properties) +(defun define-package (_name-string _version-string + &optional _docstring _requirements + &rest _extra-properties) "Define a new package. NAME-STRING is the name of the package, as a string. VERSION-STRING is the version of the package, as a string. @@ -593,31 +542,30 @@ REQUIREMENTS is a list of dependencies on other packages. where OTHER-VERSION is a string. EXTRA-PROPERTIES is currently unused." - (let* ((name (intern name-string)) - (version (version-to-list version-string)) - (new-pkg-desc (cons name - (package-desc-from-define name-string - version-string - docstring - requirements))) - (old-pkg (assq name package-alist))) - (cond - ;; If there's no old package, just add this to `package-alist'. - ((null old-pkg) - (push new-pkg-desc package-alist)) - ((version-list-< (package-desc-version (cdr old-pkg)) version) - ;; Remove the old package and declare it obsolete. - (package-mark-obsolete name (cdr old-pkg)) - (setq package-alist (cons new-pkg-desc - (delq old-pkg package-alist)))) - ;; You can have two packages with the same version, e.g. one in - ;; the system package directory and one in your private - ;; directory. We just let the first one win. - ((not (version-list-= (package-desc-version (cdr old-pkg)) version)) - ;; The package is born obsolete. - (package-mark-obsolete name (cdr new-pkg-desc)))))) - -;; From Emacs 22. + ;; FIXME: Placeholder! Should we keep it? + (error "Don't call me!")) + +(defun package-process-define-package (exp origin) + (unless (eq (car-safe exp) 'define-package) + (error "Can't find define-package in %s" origin)) + (let* ((new-pkg-desc (apply #'package-desc-from-define (cdr exp))) + (name (package-desc-name new-pkg-desc)) + (version (package-desc-version new-pkg-desc)) + (old-pkgs (assq name package-alist))) + (if (null old-pkgs) + ;; If there's no old package, just add this to `package-alist'. + (push (list name new-pkg-desc) package-alist) + ;; If there is, insert the new package at the right place in the list. + (while + (if (and (cdr old-pkgs) + (version-list-< version + (package-desc-version (cadr old-pkgs)))) + (setq old-pkgs (cdr old-pkgs)) + (push new-pkg-desc (cdr old-pkgs)) + nil))) + new-pkg-desc)) + +;; From Emacs 22, but changed so it adds to load-path. (defun package-autoload-ensure-default-file (file) "Make sure that the autoload file FILE exists and if not create it." (unless (file-exists-p file) @@ -637,6 +585,9 @@ EXTRA-PROPERTIES is currently unused." nil file)) file) +(defvar generated-autoload-file) +(defvar version-control) + (defun package-generate-autoloads (name pkg-dir) (require 'autoload) ;Load before we let-bind generated-autoload-file! (let* ((auto-name (format "%s-autoloads.el" name)) @@ -673,71 +624,79 @@ untar into a directory named DIR; otherwise, signal an error." (error "Package does not untar cleanly into directory %s/" dir))))) (tar-untar-buffer)) -(defun package-unpack (package version) - (let* ((name (symbol-name package)) - (dirname (concat name "-" version)) +(defun package-generate-description-file (pkg-desc pkg-dir) + "Create the foo-pkg.el file for single-file packages." + (let* ((name (package-desc-name pkg-desc)) + (pkg-file (expand-file-name (package--description-file pkg-dir) + pkg-dir))) + (let ((print-level nil) + (print-quoted t) + (print-length nil)) + (write-region + (concat + (prin1-to-string + (list 'define-package + (symbol-name name) + (package-version-join (package-desc-version pkg-desc)) + (package-desc-summary pkg-desc) + (let ((requires (package-desc-reqs pkg-desc))) + (list 'quote + ;; Turn version lists into string form. + (mapcar + (lambda (elt) + (list (car elt) + (package-version-join (cadr elt)))) + requires))))) + "\n") + nil + pkg-file)))) + +(defun package-unpack (pkg-desc) + "Install the contents of the current buffer as a package." + (let* ((name (package-desc-name pkg-desc)) + (dirname (package-desc-full-name pkg-desc)) (pkg-dir (expand-file-name dirname package-user-dir))) - (make-directory package-user-dir t) - ;; FIXME: should we delete PKG-DIR if it exists? - (let* ((default-directory (file-name-as-directory package-user-dir))) - (package-untar-buffer dirname) - (package--make-autoloads-and-compile package pkg-dir)))) - -(defun package--make-autoloads-and-compile (name pkg-dir) - "Generate autoloads and do byte-compilation for package named NAME. -PKG-DIR is the name of the package directory." - (let ((auto-name (package-generate-autoloads name pkg-dir)) - (load-path (cons pkg-dir load-path))) - ;; We must load the autoloads file before byte compiling, in - ;; case there are magic cookies to set up non-trivial paths. - (load auto-name nil t) - ;; FIXME: Compilation should be done as a separate, optional, step. - ;; E.g. for multi-package installs, we should first install all packages - ;; and then compile them. - (byte-recompile-directory pkg-dir 0 t))) + (pcase (package-desc-kind pkg-desc) + (`tar + (make-directory package-user-dir t) + ;; FIXME: should we delete PKG-DIR if it exists? + (let* ((default-directory (file-name-as-directory package-user-dir))) + (package-untar-buffer dirname))) + (`single + (let ((el-file (expand-file-name (format "%s.el" name) pkg-dir))) + (make-directory pkg-dir t) + (package--write-file-no-coding el-file))) + (kind (error "Unknown package kind: %S" kind))) + (package--make-autoloads-and-stuff pkg-desc pkg-dir) + ;; Update package-alist. + (let ((new-desc (package-load-descriptor pkg-dir))) + ;; FIXME: Check that `new-desc' matches `desc'! + ;; FIXME: Compilation should be done as a separate, optional, step. + ;; E.g. for multi-package installs, we should first install all packages + ;; and then compile them. + (package--compile new-desc)) + ;; Try to activate it. + (package-activate name 'force) + pkg-dir)) + +(defun package--make-autoloads-and-stuff (pkg-desc pkg-dir) + "Generate autoloads, description file, etc.. for PKG-DESC installed at PKG-DIR." + (package-generate-autoloads (package-desc-name pkg-desc) pkg-dir) + (let ((desc-file (package--description-file pkg-dir))) + (unless (file-exists-p desc-file) + (package-generate-description-file pkg-desc pkg-dir))) + ;; FIXME: Create foo.info and dir file from foo.texi? + ) + +(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)) (defun package--write-file-no-coding (file-name) (let ((buffer-file-coding-system 'no-conversion)) (write-region (point-min) (point-max) file-name))) -(defun package-unpack-single (name version desc requires) - "Install the contents of the current buffer as a package." - ;; Special case "package". FIXME: Should this still be supported? - (if (eq name 'package) - (package--write-file-no-coding - (expand-file-name (format "%s.el" name) package-user-dir)) - (let* ((pkg-dir (expand-file-name (format "%s-%s" name - (package-version-join - (version-to-list version))) - package-user-dir)) - (el-file (expand-file-name (format "%s.el" name) pkg-dir)) - (pkg-file (expand-file-name (format "%s-pkg.el" name) pkg-dir))) - (make-directory pkg-dir t) - (package--write-file-no-coding el-file) - (let ((print-level nil) - (print-quoted t) - (print-length nil)) - (write-region - (concat - (prin1-to-string - (list 'define-package - (symbol-name name) - version - desc - (when requires ;Don't bother quoting nil. - (list 'quote - ;; Turn version lists into string form. - (mapcar - (lambda (elt) - (list (car elt) - (package-version-join (cadr elt)))) - requires))))) - "\n") - nil - pkg-file - nil nil nil 'excl)) - (package--make-autoloads-and-compile name pkg-dir)))) - (defmacro package--with-work-buffer (location file &rest body) "Run BODY in a buffer containing the contents of FILE at LOCATION. LOCATION is the base location of a package archive, and should be @@ -747,6 +706,7 @@ FILE is the name of a file relative to that base location. This macro retrieves FILE from LOCATION into a temporary buffer, and evaluates BODY while that buffer is current. This work buffer is killed afterwards. Return the last value in BODY." + (declare (indent 2) (debug t)) `(let* ((http (string-match "\\`https?:" ,location)) (buffer (if http @@ -777,23 +737,15 @@ It will move point to somewhere in the headers." (let ((response (url-http-parse-response))) (when (or (< response 200) (>= response 300)) (error "Error during download request:%s" - (buffer-substring-no-properties (point) (progn - (end-of-line) - (point))))))) - -(defun package-download-single (name version desc requires) - "Download and install a single-file package." - (let ((location (package-archive-base name)) - (file (concat (symbol-name name) "-" version ".el"))) - (package--with-work-buffer location file - (package-unpack-single name version desc requires)))) + (buffer-substring-no-properties (point) (line-end-position)))))) -(defun package-download-tar (name version) +(defun package-install-from-archive (pkg-desc) "Download and install a tar package." - (let ((location (package-archive-base name)) - (file (concat (symbol-name name) "-" version ".tar"))) + (let ((location (package-archive-base pkg-desc)) + (file (concat (package-desc-full-name pkg-desc) + (package-desc-suffix pkg-desc)))) (package--with-work-buffer location file - (package-unpack name version)))) + (package-unpack pkg-desc)))) (defvar package--initialized nil) @@ -801,16 +753,17 @@ It will move point to somewhere in the headers." "Return true if PACKAGE, of MIN-VERSION or newer, is installed. MIN-VERSION should be a version list." (unless package--initialized (error "package.el is not yet initialized!")) - (let ((pkg-desc (assq package package-alist))) - (if pkg-desc - (version-list-<= min-version - (package-desc-version (cdr pkg-desc))) - ;; Also check built-in packages. - (package-built-in-p package min-version)))) - -(defun package-compute-transaction (package-list requirements) - "Return a list of packages to be installed, including PACKAGE-LIST. -PACKAGE-LIST should be a list of package names (symbols). + (or + (let ((pkg-descs (cdr (assq package package-alist)))) + (and pkg-descs + (version-list-<= min-version + (package-desc-version (car pkg-descs))))) + ;; Also check built-in packages. + (package-built-in-p package min-version))) + +(defun package-compute-transaction (packages requirements) + "Return a list of packages to be installed, including PACKAGES. +PACKAGES should be a list of `package-desc'. REQUIREMENTS should be a list of additional requirements; each element in this list should have the form (PACKAGE VERSION-LIST), @@ -821,44 +774,65 @@ This function recursively computes the requirements of the packages in REQUIREMENTS, and returns a list of all the packages that must be installed. Packages that are already installed are not included in this list." + ;; FIXME: We really should use backtracking to explore the whole + ;; search space (e.g. if foo require bar-1.3, and bar-1.4 requires toto-1.1 + ;; whereas bar-1.3 requires toto-1.0 and the user has put a hold on toto-1.0: + ;; the current code might fail to see that it could install foo by using the + ;; older bar-1.3). (dolist (elt requirements) (let* ((next-pkg (car elt)) - (next-version (cadr elt))) - (unless (package-installed-p next-pkg next-version) + (next-version (cadr elt)) + (already ())) + (dolist (pkg packages) + (if (eq next-pkg (package-desc-name pkg)) + (setq already pkg))) + (cond + (already + (if (version-list-< next-version (package-desc-version already)) + ;; Move to front, so it gets installed early enough (bug#14082). + (setq packages (cons already (delq already packages))) + (error "Need package `%s-%s', but only %s is available" + next-pkg (package-version-join next-version) + (package-version-join (package-desc-version already))))) + + ((package-installed-p next-pkg next-version) nil) + + (t ;; A package is required, but not installed. It might also be ;; blocked via `package-load-list'. - (let ((pkg-desc (cdr (assq next-pkg package-archive-contents))) - hold) - (when (setq hold (assq next-pkg package-load-list)) - (setq hold (cadr hold)) - (cond ((eq hold t)) - ((eq hold nil) - (error "Required package '%s' is disabled" - (symbol-name next-pkg))) - ((null (stringp hold)) - (error "Invalid element in `package-load-list'")) - ((version-list-< (version-to-list hold) next-version) - (error "Package `%s' held at version %s, \ + (let ((pkg-descs (cdr (assq next-pkg package-archive-contents))) + (found nil) + (problem nil)) + (while (and pkg-descs (not found)) + (let* ((pkg-desc (pop pkg-descs)) + (version (package-desc-version pkg-desc)) + (disabled (package-disabled-p next-pkg version))) + (cond + ((version-list-< version next-version) + (error + "Need package `%s-%s', but only %s is available" + next-pkg (package-version-join next-version) + (package-version-join version))) + (disabled + (unless problem + (setq problem + (if (stringp disabled) + (format "Package `%s' held at version %s, \ but version %s required" - (symbol-name next-pkg) hold - (package-version-join next-version))))) - (unless pkg-desc - (error "Package `%s-%s' is unavailable" - (symbol-name next-pkg) - (package-version-join next-version))) - (unless (version-list-<= next-version - (package-desc-version pkg-desc)) - (error - "Need package `%s-%s', but only %s is available" - (symbol-name next-pkg) (package-version-join next-version) - (package-version-join (package-desc-version pkg-desc)))) - ;; Move to front, so it gets installed early enough (bug#14082). - (setq package-list (cons next-pkg (delq next-pkg package-list))) - (setq package-list - (package-compute-transaction package-list - (package-desc-reqs - pkg-desc))))))) - package-list) + next-pkg disabled + (package-version-join next-version)) + (format "Required package '%s' is disabled" + next-pkg))))) + (t (setq found pkg-desc))))) + (unless found + (if problem + (error problem) + (error "Package `%s-%s' is unavailable" + next-pkg (package-version-join next-version)))) + (setq packages + (package-compute-transaction (cons found packages) + (package-desc-reqs found)))))))) + packages) (defun package-read-from-string (str) "Read a Lisp expression from STR. @@ -902,10 +876,9 @@ If successful, set the variable `package-archive-contents'. If the archive version is too new, signal an error." ;; Version 1 of 'archive-contents' is identical to our internal ;; representation. - (let* ((dir (concat "archives/" archive)) - (contents-file (concat dir "/archive-contents")) - contents) - (when (setq contents (package--read-archive-file contents-file)) + (let* ((contents-file (format "archives/%s/archive-contents" archive)) + (contents (package--read-archive-file contents-file))) + (when contents (dolist (package contents) (package--add-to-archive-contents package archive))))) @@ -923,66 +896,51 @@ If the archive version is too new, signal an error." PACKAGE should have the form (NAME . PACKAGE--AC-DESC). Also, add the originating archive to the `package-desc' structure." (let* ((name (car package)) + (version (package--ac-desc-version (cdr package))) (pkg-desc (package-desc-create :name name - :version (package--ac-desc-version (cdr package)) + :version version :reqs (package--ac-desc-reqs (cdr package)) :summary (package--ac-desc-summary (cdr package)) :kind (package--ac-desc-kind (cdr package)) :archive archive)) - (entry (cons name pkg-desc)) - (existing-package (assq name package-archive-contents)) + (existing-packages (assq name package-archive-contents)) (pinned-to-archive (assoc name package-pinned-packages))) - (cond ((and pinned-to-archive - ;; If pinned to another archive, skip entirely. - (not (equal (cdr pinned-to-archive) archive))) - nil) - ((not existing-package) - (push entry package-archive-contents)) - ((version-list-< (package-desc-version (cdr existing-package)) - (package-desc-version pkg-desc)) - ;; Replace the entry with this one. - (setq package-archive-contents - (cons entry - (delq existing-package - package-archive-contents))))))) - -(defun package-download-transaction (package-list) - "Download and install all the packages in PACKAGE-LIST. -PACKAGE-LIST should be a list of package names (symbols). + (cond + ;; Skip entirely if pinned to another archive or already installed. + ((or (and pinned-to-archive + (not (equal (cdr pinned-to-archive) archive))) + (let ((bi (assq name package--builtin-versions))) + (and bi (version-list-= version (cdr bi)))) + (let ((ins (cdr (assq name package-alist)))) + (and ins (version-list-= version + (package-desc-version (car ins)))))) + nil) + ((not existing-packages) + (push (list name pkg-desc) package-archive-contents)) + (t + (while + (if (and (cdr existing-packages) + (version-list-< + version (package-desc-version (cadr existing-packages)))) + (setq existing-packages (cdr existing-packages)) + (push pkg-desc (cdr existing-packages)) + nil)))))) + +(defun package-download-transaction (packages) + "Download and install all the packages in PACKAGES. +PACKAGES should be a list of package-desc. This function assumes that all package requirements in -PACKAGE-LIST are satisfied, i.e. that PACKAGE-LIST is computed +PACKAGES are satisfied, i.e. that PACKAGES is computed using `package-compute-transaction'." - (dolist (elt package-list) - (let* ((desc (cdr (assq elt package-archive-contents))) - ;; As an exception, if package is "held" in - ;; `package-load-list', download the held version. - (hold (cadr (assq elt package-load-list))) - (v-string (or (and (stringp hold) hold) - (package-version-join (package-desc-version desc)))) - (kind (package-desc-kind desc))) - (cond - ((eq kind 'tar) - (package-download-tar elt v-string)) - ((eq kind 'single) - (package-download-single elt v-string - (package-desc-summary desc) - (package-desc-reqs desc))) - (t - (error "Unknown package kind: %s" (symbol-name kind)))) - ;; If package A depends on package B, then A may `require' B - ;; during byte compilation. So we need to activate B before - ;; unpacking A. - (package-maybe-load-descriptor (symbol-name elt) v-string - package-user-dir) - (package-activate elt (version-to-list v-string))))) + (mapc #'package-install-from-archive packages)) ;;;###autoload -(defun package-install (name) - "Install the package named NAME. -NAME should be the name of one of the available packages in an -archive in `package-archives'. Interactively, prompt for NAME." +(defun package-install (pkg) + "Install the package PKG. +PKG can be a package-desc or the package name of one the available packages +in an archive in `package-archives'. Interactively, prompt for its name." (interactive (progn ;; Initialize the package system to get the list of package @@ -992,19 +950,16 @@ archive in `package-archives'. Interactively, prompt for NAME." (unless package-archive-contents (package-refresh-contents)) (list (intern (completing-read - "Install package: " - (mapcar (lambda (elt) - (cons (symbol-name (car elt)) - nil)) - package-archive-contents) - nil t))))) - (let ((pkg-desc (assq name package-archive-contents))) - (unless pkg-desc - (error "Package `%s' is not available for installation" - (symbol-name name))) - (package-download-transaction - (package-compute-transaction (list name) - (package-desc-reqs (cdr pkg-desc)))))) + "Install package: " + (mapcar (lambda (elt) (symbol-name (car elt))) + package-archive-contents) + nil t))))) + (package-download-transaction + (if (package-desc-p pkg) + (package-compute-transaction (list pkg) + (package-desc-reqs pkg)) + (package-compute-transaction () + (list (list pkg)))))) (defun package-strip-rcs-id (str) "Strip RCS version ID from the version string STR. @@ -1051,63 +1006,51 @@ boundaries." (if requires-str (package-read-from-string requires-str)) :kind 'single)))) -(defun package-tar-file-info (file) +(declare-function tar-get-file-descriptor "tar-mode" (file)) +(declare-function tar--extract "tar-mode" (descriptor)) + +(defun package-tar-file-info () "Find package information for a tar file. -FILE is the name of the tar file to examine. -The return result is a vector like `package-buffer-info'." - (let ((default-directory (file-name-directory file)) - (file (file-name-nondirectory file))) - (unless (string-match (concat "\\`" package-subdirectory-regexp "\\.tar\\'") - file) - (error "Invalid package name `%s'" file)) - (let* ((pkg-name (match-string-no-properties 1 file)) - (pkg-version (match-string-no-properties 2 file)) - ;; Extract the package descriptor. - (pkg-def-contents (shell-command-to-string - ;; Requires GNU tar. - (concat "tar -xOf " file " " - pkg-name "-" pkg-version "/" - pkg-name "-pkg.el"))) - (pkg-def-parsed (package-read-from-string pkg-def-contents))) - (unless (eq (car pkg-def-parsed) 'define-package) - (error "No `define-package' sexp is present in `%s-pkg.el'" pkg-name)) - (let ((pkg-desc - (apply #'package-desc-from-define (append (cdr pkg-def-parsed) - '(:kind tar))))) - (unless (equal pkg-version - (package-version-join (package-desc-version pkg-desc))) - (error "Package has inconsistent versions")) - (unless (equal pkg-name (symbol-name (package-desc-name pkg-desc))) - (error "Package has inconsistent names")) - pkg-desc)))) +The return result is a `package-desc'." + (cl-assert (derived-mode-p 'tar-mode)) + (let* ((dir-name (file-name-directory + (tar-header-name (car tar-parse-info)))) + (desc-file (package--description-file dir-name)) + (tar-desc (tar-get-file-descriptor (concat dir-name desc-file)))) + (unless tar-desc + (error "No package descriptor file found")) + (with-current-buffer (tar--extract tar-desc) + (goto-char (point-min)) + (unwind-protect + (let* ((pkg-def-parsed (read (current-buffer))) + (pkg-desc + (if (not (eq (car pkg-def-parsed) 'define-package)) + (error "Can't find define-package in %s" + (tar-header-name tar-desc)) + (apply #'package-desc-from-define + (append (cdr pkg-def-parsed)))))) + (setf (package-desc-kind pkg-desc) 'tar) + pkg-desc) + (kill-buffer (current-buffer)))))) ;;;###autoload -(defun package-install-from-buffer (pkg-desc) +(defun package-install-from-buffer () "Install a package from the current buffer. -When called interactively, the current buffer is assumed to be a -single .el file that follows the packaging guidelines; see info -node `(elisp)Packaging'. - -When called from Lisp, PKG-DESC is a `package-desc' describing the -information)." - (interactive (list (package-buffer-info))) - (save-excursion - (save-restriction - (let* ((name (package-desc-name pkg-desc)) - (requires (package-desc-reqs pkg-desc)) - (desc (package-desc-summary pkg-desc)) - (pkg-version (package-desc-version pkg-desc))) - ;; Download and install the dependencies. - (let ((transaction (package-compute-transaction nil requires))) - (package-download-transaction transaction)) - ;; Install the package itself. - (pcase (package-desc-kind pkg-desc) - (`single (package-unpack-single name pkg-version desc requires)) - (`tar (package-unpack name pkg-version)) - (type (error "Unknown type: %S" type))) - ;; Try to activate it. - (package-initialize))))) +The current buffer is assumed to be a single .el or .tar file that follows the +packaging guidelines; see info node `(elisp)Packaging'. +Downloads and installs required packages as needed." + (interactive) + (let ((pkg-desc (if (derived-mode-p 'tar-mode) + (package-tar-file-info) + (package-buffer-info)))) + ;; Download and install the dependencies. + (let* ((requires (package-desc-reqs pkg-desc)) + (transaction (package-compute-transaction nil requires))) + (package-download-transaction transaction)) + ;; Install the package itself. + (package-unpack pkg-desc) + pkg-desc)) ;;;###autoload (defun package-install-file (file) @@ -1116,37 +1059,34 @@ The file can either be a tar file or an Emacs Lisp file." (interactive "fPackage file name: ") (with-temp-buffer (insert-file-contents-literally file) - (cond - ((string-match "\\.el\\'" file) - (package-install-from-buffer (package-buffer-info))) - ((string-match "\\.tar\\'" file) - (package-install-from-buffer (package-tar-file-info file))) - (t (error "Unrecognized extension `%s'" (file-name-extension file)))))) - -(defun package-delete (name version) - (let ((dir (package--dir name version))) - (if (string-equal (file-name-directory dir) - (file-name-as-directory - (expand-file-name package-user-dir))) - (progn - (delete-directory dir t t) - (message "Package `%s-%s' deleted." name version)) - ;; Don't delete "system" packages - (error "Package `%s-%s' is a system package, not deleting" - name version)))) - -(defun package-archive-base (name) + (when (string-match "\\.tar\\'" file) (tar-mode)) + (package-install-from-buffer))) + +(defun package-delete (pkg-desc) + (let ((dir (package-desc-dir pkg-desc))) + (if (not (string-prefix-p (file-name-as-directory + (expand-file-name package-user-dir)) + (expand-file-name dir))) + ;; Don't delete "system" packages. + (error "Package `%s' is a system package, not deleting" + (package-desc-full-name pkg-desc)) + (delete-directory dir t t) + ;; Update package-alist. + (let* ((name (package-desc-name pkg-desc))) + (delete pkg-desc (assq name package-alist))) + (message "Package `%s' deleted." (package-desc-full-name pkg-desc))))) + +(defun package-archive-base (desc) "Return the archive containing the package NAME." - (let ((desc (cdr (assq (intern-soft name) package-archive-contents)))) - (cdr (assoc (package-desc-archive desc) package-archives)))) + (cdr (assoc (package-desc-archive desc) package-archives))) (defun package--download-one-archive (archive file) "Retrieve an archive file FILE from ARCHIVE, and cache it. ARCHIVE should be a cons cell of the form (NAME . LOCATION), similar to an entry in `package-alist'. Save the cached copy to \"archives/NAME/archive-contents\" in `package-user-dir'." - (let* ((dir (expand-file-name "archives" package-user-dir)) - (dir (expand-file-name (car archive) dir))) + (let* ((dir (expand-file-name (format "archives/%s" (car archive)) + package-user-dir))) (package--with-work-buffer (cdr archive) file ;; Read the retrieved buffer to make sure it is valid (e.g. it ;; may fetch a URL redirect page). @@ -1162,6 +1102,7 @@ similar to an entry in `package-alist'. Save the cached copy to This informs Emacs about the latest versions of all packages, and makes them available for download." (interactive) + ;; FIXME: Do it asynchronously. (unless (file-exists-p package-user-dir) (make-directory package-user-dir t)) (dolist (archive package-archives) @@ -1177,13 +1118,12 @@ makes them available for download." The variable `package-load-list' controls which packages to load. If optional arg NO-ACTIVATE is non-nil, don't activate packages." (interactive) - (setq package-alist nil - package-obsolete-alist nil) + (setq package-alist nil) (package-load-all-descriptors) (package-read-all-archive-contents) (unless no-activate (dolist (elt package-alist) - (package-activate (car elt) (package-desc-version (cdr elt))))) + (package-activate (car elt)))) (setq package--initialized t)) @@ -1193,26 +1133,25 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (defun describe-package (package) "Display the full documentation of PACKAGE (a symbol)." (interactive - (let* ((guess (function-called-at-point)) - packages val) + (let* ((guess (function-called-at-point))) (require 'finder-inf nil t) ;; Load the package list if necessary (but don't activate them). (unless package--initialized (package-initialize t)) - (setq packages (append (mapcar 'car package-alist) - (mapcar 'car package-archive-contents) - (mapcar 'car package--builtins))) - (unless (memq guess packages) - (setq guess nil)) - (setq packages (mapcar 'symbol-name packages)) - (setq val - (completing-read (if guess - (format "Describe package (default %s): " - guess) - "Describe package: ") - packages nil t nil nil guess)) - (list (if (equal val "") guess (intern val))))) - (if (or (null package) (not (symbolp package))) + (let ((packages (append (mapcar 'car package-alist) + (mapcar 'car package-archive-contents) + (mapcar 'car package--builtins)))) + (unless (memq guess packages) + (setq guess nil)) + (setq packages (mapcar 'symbol-name packages)) + (let ((val + (completing-read (if guess + (format "Describe package (default %s): " + guess) + "Describe package: ") + packages nil t nil nil guess))) + (list (intern val)))))) + (if (not (or (package-desc-p package) (and package (symbolp package)))) (message "No package specified") (help-setup-xref (list #'describe-package package) (called-interactively-p 'interactive)) @@ -1220,57 +1159,52 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (with-current-buffer standard-output (describe-package-1 package))))) -(defun describe-package-1 (package) +(defun describe-package-1 (pkg) (require 'lisp-mnt) - (let ((package-name (symbol-name package)) - (built-in (assq package package--builtins)) - desc pkg-dir reqs version installable archive) - (prin1 package) + (let* ((desc (or + (if (package-desc-p pkg) pkg) + (cadr (assq pkg package-alist)) + (let ((built-in (assq pkg package--builtins))) + (if built-in + (package--from-builtin built-in) + (cadr (assq pkg package-archive-contents)))))) + (name (if desc (package-desc-name desc) pkg)) + (pkg-dir (if desc (package-desc-dir desc))) + (reqs (if desc (package-desc-reqs desc))) + (version (if desc (package-desc-version desc))) + (archive (if desc (package-desc-archive desc))) + (built-in (eq pkg-dir 'builtin)) + (installable (and archive (not built-in))) + (status (if desc (package-desc-status desc) "orphan"))) + (prin1 name) (princ " is ") - (cond - ;; Loaded packages are in `package-alist'. - ((setq desc (cdr (assq package package-alist))) - (setq version (package-version-join (package-desc-version desc))) - (if (setq pkg-dir (package--dir package-name version)) - (insert "an installed package.\n\n") - ;; This normally does not happen. - (insert "a deleted package.\n\n"))) - ;; Available packages are in `package-archive-contents'. - ((setq desc (cdr (assq package package-archive-contents))) - (setq version (package-version-join (package-desc-version desc)) - archive (package-desc-archive desc) - installable t) - (if built-in - (insert "a built-in package.\n\n") - (insert "an uninstalled package.\n\n"))) - (built-in - (setq desc (package--from-builtin built-in) - version (package-version-join (package-desc-version desc))) - (insert "a built-in package.\n\n")) - (t - (insert "an orphan package.\n\n"))) + (princ (if (memq (aref status 0) '(?a ?e ?i ?o ?u)) "an " "a ")) + (princ status) + (princ " package.\n\n") (insert " " (propertize "Status" 'font-lock-face 'bold) ": ") - (cond (pkg-dir - (insert (propertize "Installed" + (cond (built-in + (insert (propertize (capitalize status) + 'font-lock-face 'font-lock-builtin-face) + ".")) + (pkg-dir + (insert (propertize (capitalize status) ;FIXME: Why comment-face? 'font-lock-face 'font-lock-comment-face)) (insert " in `") ;; Todo: Add button for uninstalling. - (help-insert-xref-button (file-name-as-directory pkg-dir) + (help-insert-xref-button (abbreviate-file-name + (file-name-as-directory pkg-dir)) 'help-package-def pkg-dir) - (if built-in + (if (and (package-built-in-p name) + (not (package-built-in-p name version))) (insert "',\n shadowing a " (propertize "built-in package" 'font-lock-face 'font-lock-builtin-face) ".") (insert "'."))) (installable - (if built-in - (insert (propertize "Built-in." - 'font-lock-face 'font-lock-builtin-face) - " Alternate version available") - (insert "Available")) - (insert " from " archive) + (insert (capitalize status)) + (insert " from " (format "%s" archive)) (insert " -- ") (let ((button-text (if (display-graphic-p) "Install" "[Install]")) (button-face (if (display-graphic-p) @@ -1279,16 +1213,14 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." :foreground "black") 'link))) (insert-text-button button-text 'face button-face 'follow-link t - 'package-symbol package + 'package-desc desc 'action 'package-install-button-action))) - (built-in - (insert (propertize "Built-in." - 'font-lock-face 'font-lock-builtin-face))) - (t (insert "Deleted."))) + (t (insert (capitalize status) "."))) (insert "\n") - (and version (> (length version) 0) + (and version (insert " " - (propertize "Version" 'font-lock-face 'bold) ": " version "\n")) + (propertize "Version" 'font-lock-face 'bold) ": " + (package-version-join version) "\n")) (setq reqs (if desc (package-desc-reqs desc))) (when reqs @@ -1308,11 +1240,38 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (help-insert-xref-button text 'help-package name)) (insert "\n"))) (insert " " (propertize "Summary" 'font-lock-face 'bold) - ": " (if desc (package-desc-summary desc)) "\n\n") + ": " (if desc (package-desc-summary desc)) "\n") + + (let* ((all-pkgs (append (cdr (assq name package-alist)) + (cdr (assq name package-archive-contents)) + (let ((bi (assq name package--builtins))) + (if bi (list (package--from-builtin bi)))))) + (other-pkgs (delete desc all-pkgs))) + (when other-pkgs + (insert " " (propertize "Other versions" 'font-lock-face 'bold) ": " + (mapconcat + (lambda (opkg) + (let* ((ov (package-desc-version opkg)) + (dir (package-desc-dir opkg)) + (from (or (package-desc-archive opkg) + (if (stringp dir) "installed" dir)))) + (if (not ov) (format "%s" from) + (format "%s (%s)" + (make-text-button (package-version-join ov) nil + 'face 'link + 'follow-link t + 'action + (lambda (_button) + (describe-package opkg))) + from)))) + other-pkgs ", ") + ".\n"))) + + (insert "\n") (if built-in ;; For built-in packages, insert the commentary. - (let ((fn (locate-file (concat package-name ".el") load-path + (let ((fn (locate-file (format "%s.el" name) load-path load-file-rep-suffixes)) (opoint (point))) (insert (or (lm-commentary fn) "")) @@ -1322,14 +1281,15 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (replace-match "")) (while (re-search-forward "^\\(;+ ?\\)" nil t) (replace-match "")))) - (let ((readme (expand-file-name (concat package-name "-readme.txt") + (let ((readme (expand-file-name (format "%s-readme.txt" name) package-user-dir)) readme-string) ;; For elpa packages, try downloading the commentary. If that ;; fails, try an existing readme file in `package-user-dir'. (cond ((condition-case nil - (package--with-work-buffer (package-archive-base package) - (concat package-name "-readme.txt") + (package--with-work-buffer + (package-archive-base desc) + (format "%s-readme.txt" name) (setq buffer-file-name (expand-file-name readme package-user-dir)) (let ((version-control 'never)) @@ -1343,9 +1303,10 @@ If optional arg NO-ACTIVATE is non-nil, don't activate packages." (goto-char (point-max)))))))) (defun package-install-button-action (button) - (let ((package (button-get button 'package-symbol))) - (when (y-or-n-p (format "Install package `%s'? " package)) - (package-install package) + (let ((pkg-desc (button-get button 'package-desc))) + (when (y-or-n-p (format "Install package `%s'? " + (package-desc-full-name pkg-desc))) + (package-install pkg-desc) (revert-buffer nil t) (goto-char (point-min))))) @@ -1432,91 +1393,121 @@ Letters do not insert themselves; instead, they are commands. ("Description" 0 nil)]) (setq tabulated-list-padding 2) (setq tabulated-list-sort-key (cons "Status" nil)) + (add-hook 'tabulated-list-revert-hook 'package-menu--refresh) (tabulated-list-init-header)) -(defmacro package--push (package desc status listname) +(defmacro package--push (pkg-desc status listname) "Convenience macro for `package-menu--generate'. If the alist stored in the symbol LISTNAME lacks an entry for a -package PACKAGE with descriptor DESC, add one. The alist is -keyed with cons cells (PACKAGE . VERSION-LIST), where PACKAGE is -a symbol and VERSION-LIST is a version list." - `(let* ((version (package-desc-version ,desc)) - (key (cons ,package version))) - (unless (assoc key ,listname) - (push (list key ,status (package-desc-summary ,desc)) ,listname)))) +package PKG-DESC, add one. The alist is keyed with PKG-DESC." + `(unless (assoc ,pkg-desc ,listname) + ;; FIXME: Should we move status into pkg-desc? + (push (cons ,pkg-desc ,status) ,listname))) -(defun package-menu--generate (remember-pos packages) - "Populate the Package Menu. -If REMEMBER-POS is non-nil, keep point on the same entry. -PACKAGES should be t, which means to display all known packages, -or a list of package names (symbols) to display." - ;; Construct list of ((PACKAGE . VERSION) STATUS DESCRIPTION). +(defvar package-list-unversioned nil + "If non-nil include packages that don't have a version in `list-package'.") + +(defun package-desc-status (pkg-desc) + (let* ((name (package-desc-name pkg-desc)) + (dir (package-desc-dir pkg-desc)) + (lle (assq name package-load-list)) + (held (cadr lle)) + (version (package-desc-version pkg-desc))) + (cond + ((eq dir 'builtin) "built-in") + ((and lle (null held)) "disabled") + ((stringp held) + (let ((hv (if (stringp held) (version-to-list held)))) + (cond + ((version-list-= version hv) "held") + ((version-list-< version hv) "obsolete") + (t "disabled")))) + ((package-built-in-p name version) "obsolete") + (dir ;One of the installed packages. + (cond + ((not (file-exists-p (package-desc-dir pkg-desc))) "deleted") + ((eq pkg-desc (cadr (assq name package-alist))) "installed") + (t "obsolete"))) + (t + (let* ((ins (cadr (assq name package-alist))) + (ins-v (if ins (package-desc-version ins)))) + (cond + ((or (null ins) (version-list-< ins-v version)) + (if (memq name package-menu--new-package-list) + "new" "available")) + ((version-list-< version ins-v) "obsolete") + ((version-list-= version ins-v) "installed"))))))) + +(defun package-menu--refresh (&optional packages) + "Re-populate the `tabulated-list-entries'. +PACKAGES should be nil or t, which means to display all known packages." + ;; Construct list of (PKG-DESC . STATUS). + (unless packages (setq packages t)) (let (info-list name) ;; Installed packages: (dolist (elt package-alist) (setq name (car elt)) (when (or (eq packages t) (memq name packages)) - (package--push name (cdr elt) - (if (stringp (cadr (assq name package-load-list))) - "held" "installed") - info-list))) + (dolist (pkg (cdr elt)) + (package--push pkg (package-desc-status pkg) info-list)))) ;; Built-in packages: (dolist (elt package--builtins) (setq name (car elt)) (when (and (not (eq name 'emacs)) ; Hide the `emacs' package. + (or package-list-unversioned + (package--bi-desc-version (cdr elt))) (or (eq packages t) (memq name packages))) - (package--push name (package--from-builtin elt) "built-in" info-list))) + (package--push (package--from-builtin elt) "built-in" info-list))) ;; Available and disabled packages: (dolist (elt package-archive-contents) (setq name (car elt)) (when (or (eq packages t) (memq name packages)) - (let ((hold (assq name package-load-list))) - (package--push name (cdr elt) - (cond - ((and hold (null (cadr hold))) "disabled") - ((memq name package-menu--new-package-list) "new") - (t "available")) - info-list)))) - - ;; Obsolete packages: - (dolist (elt package-obsolete-alist) - (dolist (inner-elt (cdr elt)) - (when (or (eq packages t) (memq (car elt) packages)) - (package--push (car elt) (cdr inner-elt) "obsolete" info-list)))) + (dolist (pkg (cdr elt)) + ;; Hide obsolete packages. + (unless (package-installed-p (package-desc-name pkg) + (package-desc-version pkg)) + (package--push pkg (package-desc-status pkg) info-list))))) ;; Print the result. - (setq tabulated-list-entries (mapcar 'package-menu--print-info info-list)) - (tabulated-list-print remember-pos))) + (setq tabulated-list-entries + (mapcar #'package-menu--print-info info-list)))) + +(defun package-menu--generate (remember-pos packages) + "Populate the Package Menu. + If REMEMBER-POS is non-nil, keep point on the same entry. +PACKAGES should be t, which means to display all known packages, +or a list of package names (symbols) to display." + (package-menu--refresh packages) + (tabulated-list-print remember-pos)) (defun package-menu--print-info (pkg) "Return a package entry suitable for `tabulated-list-entries'. -PKG has the form ((PACKAGE . VERSION) STATUS DOC). -Return (KEY [NAME VERSION STATUS DOC]), where KEY is the -identifier (NAME . VERSION-LIST)." - (let* ((package (caar pkg)) - (version (cdr (car pkg))) - (status (nth 1 pkg)) - (doc (or (nth 2 pkg) "")) - (face (cond - ((string= status "built-in") 'font-lock-builtin-face) - ((string= status "available") 'default) - ((string= status "new") 'bold) - ((string= status "held") 'font-lock-constant-face) - ((string= status "disabled") 'font-lock-warning-face) - ((string= status "installed") 'font-lock-comment-face) - (t 'font-lock-warning-face)))) ; obsolete. - (list (cons package version) - (vector (list (symbol-name package) +PKG has the form (PKG-DESC . STATUS). +Return (PKG-DESC [NAME VERSION STATUS DOC])." + (let* ((pkg-desc (car pkg)) + (status (cdr pkg)) + (face (pcase status + (`"built-in" 'font-lock-builtin-face) + (`"available" 'default) + (`"new" 'bold) + (`"held" 'font-lock-constant-face) + (`"disabled" 'font-lock-warning-face) + (`"installed" 'font-lock-comment-face) + (_ 'font-lock-warning-face)))) ; obsolete. + (list pkg-desc + (vector (list (symbol-name (package-desc-name pkg-desc)) 'face 'link 'follow-link t - 'package-symbol package + 'package-desc pkg-desc 'action 'package-menu-describe-package) - (propertize (package-version-join version) + (propertize (package-version-join + (package-desc-version pkg-desc)) 'font-lock-face face) (propertize status 'font-lock-face face) - (propertize doc 'font-lock-face face))))) + (propertize (package-desc-summary pkg-desc) + 'font-lock-face face))))) (defun package-menu-refresh () "Download the Emacs Lisp package archive. @@ -1532,10 +1523,11 @@ This fetches the contents of each archive specified in "Describe the current package. If optional arg BUTTON is non-nil, describe its associated package." (interactive) - (let ((package (if button (button-get button 'package-symbol) - (car (tabulated-list-get-id))))) - (if package - (describe-package package)))) + (let ((pkg-desc (if button (button-get button 'package-desc) + (tabulated-list-get-id)))) + (if pkg-desc + (describe-package pkg-desc) + (error "No package here")))) ;; fixme numeric argument (defun package-menu-mark-delete (&optional _num) @@ -1582,8 +1574,8 @@ If optional arg BUTTON is non-nil, describe its associated package." 'package-menu-view-commentary 'package-menu-describe-package "24.1") (defun package-menu-get-status () - (let* ((pkg (tabulated-list-get-id)) - (entry (and pkg (assq pkg tabulated-list-entries)))) + (let* ((id (tabulated-list-get-id)) + (entry (and id (assq id tabulated-list-entries)))) (if entry (aref (cadr entry) 2) ""))) @@ -1592,18 +1584,20 @@ If optional arg BUTTON is non-nil, describe its associated package." (let (installed available upgrades) ;; Build list of installed/available packages in this buffer. (dolist (entry tabulated-list-entries) - ;; ENTRY is ((NAME . VERSION) [NAME VERSION STATUS DOC]) - (let ((pkg (car entry)) + ;; ENTRY is (PKG-DESC [NAME VERSION STATUS DOC]) + (let ((pkg-desc (car entry)) (status (aref (cadr entry) 2))) (cond ((equal status "installed") - (push pkg installed)) + (push pkg-desc installed)) ((member status '("available" "new")) - (push pkg available))))) - ;; Loop through list of installed packages, finding upgrades - (dolist (pkg installed) - (let ((avail-pkg (assq (car pkg) available))) + (push (cons (package-desc-name pkg-desc) pkg-desc) + available))))) + ;; Loop through list of installed packages, finding upgrades. + (dolist (pkg-desc installed) + (let ((avail-pkg (assq (package-desc-name pkg-desc) available))) (and avail-pkg - (version-list-< (cdr pkg) (cdr avail-pkg)) + (version-list-< (package-desc-version pkg-desc) + (package-desc-version (cdr avail-pkg))) (push avail-pkg upgrades)))) upgrades)) @@ -1623,11 +1617,11 @@ call will upgrade the package." (save-excursion (goto-char (point-min)) (while (not (eobp)) - (let* ((pkg (tabulated-list-get-id)) - (upgrade (assq (car pkg) upgrades))) + (let* ((pkg-desc (tabulated-list-get-id)) + (upgrade (cdr (assq (package-desc-name pkg-desc) upgrades)))) (cond ((null upgrade) (forward-line 1)) - ((equal pkg upgrade) + ((equal pkg-desc upgrade) (package-menu-mark-install)) (t (package-menu-mark-delete)))))) @@ -1643,30 +1637,30 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." (interactive) (unless (derived-mode-p 'package-menu-mode) (error "The current buffer is not in Package Menu mode")) - (let (install-list delete-list cmd id) + (let (install-list delete-list cmd pkg-desc) (save-excursion (goto-char (point-min)) (while (not (eobp)) (setq cmd (char-after)) (unless (eq cmd ?\s) - ;; This is the key (PACKAGE . VERSION-LIST). - (setq id (tabulated-list-get-id)) + ;; This is the key PKG-DESC. + (setq pkg-desc (tabulated-list-get-id)) (cond ((eq cmd ?D) - (push (cons (symbol-name (car id)) - (package-version-join (cdr id))) - delete-list)) + (push pkg-desc delete-list)) ((eq cmd ?I) - (push (car id) install-list)))) + (push pkg-desc install-list)))) (forward-line))) (when install-list (if (or noquery (yes-or-no-p - (if (= (length install-list) 1) - (format "Install package `%s'? " (car install-list)) - (format "Install these %d packages (%s)? " - (length install-list) - (mapconcat 'symbol-name install-list ", "))))) + (if (= (length install-list) 1) + (format "Install package `%s'? " + (package-desc-full-name (car install-list))) + (format "Install these %d packages (%s)? " + (length install-list) + (mapconcat #'package-desc-full-name + install-list ", "))))) (mapc 'package-install install-list))) ;; Delete packages, prompting if necessary. (when delete-list @@ -1674,24 +1668,17 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." noquery (yes-or-no-p (if (= (length delete-list) 1) - (format "Delete package `%s-%s'? " - (caar delete-list) - (cdr (car delete-list))) + (format "Delete package `%s'? " + (package-desc-full-name (car delete-list))) (format "Delete these %d packages (%s)? " (length delete-list) - (mapconcat (lambda (elt) - (concat (car elt) "-" (cdr elt))) - delete-list - ", "))))) + (mapconcat #'package-desc-full-name + delete-list ", "))))) (dolist (elt delete-list) (condition-case-unless-debug err - (package-delete (car elt) (cdr elt)) + (package-delete elt) (error (message (cadr err))))) (error "Aborted"))) - ;; If we deleted anything, regenerate `package-alist'. This is done - ;; automatically if we installed a package. - (and delete-list (null install-list) - (package-initialize)) (if (or delete-list install-list) (package-menu--generate t t) (message "No operations specified.")))) @@ -1730,8 +1717,8 @@ Optional argument NOQUERY non-nil means do not ask the user to confirm." (string< dA dB)))) (defun package-menu--name-predicate (A B) - (string< (symbol-name (caar A)) - (symbol-name (caar B)))) + (string< (symbol-name (package-desc-name (car A))) + (symbol-name (package-desc-name (car B))))) ;;;###autoload (defun list-packages (&optional no-fetch) diff --git a/lisp/emacs-lisp/tabulated-list.el b/lisp/emacs-lisp/tabulated-list.el index 5660ac8c4cc..9c5115bcd7b 100644 --- a/lisp/emacs-lisp/tabulated-list.el +++ b/lisp/emacs-lisp/tabulated-list.el @@ -41,7 +41,7 @@ ;; major mode, switch back, and have the original Tabulated List data ;; still valid. See, for example, ebuff-menu.el. -(defvar tabulated-list-format nil +(defvar-local tabulated-list-format nil "The format of the current Tabulated List mode buffer. This should be a vector of elements (NAME WIDTH SORT . PROPS), where: @@ -58,17 +58,15 @@ where: of `tabulated-list-entries'. - PROPS is a plist of additional column properties. Currently supported properties are: - - `:right-align': if non-nil, the column should be right-aligned. + - `:right-align': If non-nil, the column should be right-aligned. - `:pad-right': Number of additional padding spaces to the right of the column (defaults to 1 if omitted).") -(make-variable-buffer-local 'tabulated-list-format) (put 'tabulated-list-format 'permanent-local t) -(defvar tabulated-list-use-header-line t +(defvar-local tabulated-list-use-header-line t "Whether the Tabulated List buffer should use a header line.") -(make-variable-buffer-local 'tabulated-list-use-header-line) -(defvar tabulated-list-entries nil +(defvar-local tabulated-list-entries nil "Entries displayed in the current Tabulated List buffer. This should be either a function, or a list. If a list, each element has the form (ID [DESC1 ... DESCN]), @@ -86,28 +84,25 @@ where: If `tabulated-list-entries' is a function, it is called with no arguments and must return a list of the above form.") -(make-variable-buffer-local 'tabulated-list-entries) (put 'tabulated-list-entries 'permanent-local t) -(defvar tabulated-list-padding 0 +(defvar-local tabulated-list-padding 0 "Number of characters preceding each Tabulated List mode entry. By default, lines are padded with spaces, but you can use the function `tabulated-list-put-tag' to change this.") -(make-variable-buffer-local 'tabulated-list-padding) (put 'tabulated-list-padding 'permanent-local t) (defvar tabulated-list-revert-hook nil "Hook run before reverting a Tabulated List buffer. This is commonly used to recompute `tabulated-list-entries'.") -(defvar tabulated-list-printer 'tabulated-list-print-entry +(defvar-local tabulated-list-printer 'tabulated-list-print-entry "Function for inserting a Tabulated List entry at point. It is called with two arguments, ID and COLS. ID is a Lisp object identifying the entry, and COLS is a vector of column descriptors, as documented in `tabulated-list-entries'.") -(make-variable-buffer-local 'tabulated-list-printer) -(defvar tabulated-list-sort-key nil +(defvar-local tabulated-list-sort-key nil "Sort key for the current Tabulated List mode buffer. If nil, no additional sorting is performed. Otherwise, this should be a cons cell (NAME . FLIP). @@ -115,7 +110,6 @@ NAME is a string matching one of the column names in `tabulated-list-format' (the corresponding SORT entry in `tabulated-list-format' then specifies how to sort). FLIP, if non-nil, means to invert the resulting sort.") -(make-variable-buffer-local 'tabulated-list-sort-key) (put 'tabulated-list-sort-key 'permanent-local t) (defsubst tabulated-list-get-id (&optional pos) @@ -236,7 +230,7 @@ If ADVANCE is non-nil, move forward by one line afterwards." `(space :align-to ,(+ x shift))) (cdr cols)))) (setq x (+ x shift))))) - (if (> pad-right 0) + (if (>= pad-right 0) (push (propertize " " 'display `(space :align-to ,next-x) 'face 'fixed-pitch) @@ -246,7 +240,7 @@ If ADVANCE is non-nil, move forward by one line afterwards." (if tabulated-list-use-header-line (setq header-line-format cols) (setq header-line-format nil) - (set (make-local-variable 'tabulated-list--header-string) cols)))) + (setq-local tabulated-list--header-string cols)))) (defun tabulated-list-print-fake-header () "Insert a fake Tabulated List \"header line\" at the start of the buffer." @@ -255,8 +249,8 @@ If ADVANCE is non-nil, move forward by one line afterwards." (insert tabulated-list--header-string "\n") (if tabulated-list--header-overlay (move-overlay tabulated-list--header-overlay (point-min) (point)) - (set (make-local-variable 'tabulated-list--header-overlay) - (make-overlay (point-min) (point)))) + (setq-local tabulated-list--header-overlay + (make-overlay (point-min) (point)))) (overlay-put tabulated-list--header-overlay 'face 'underline))) (defun tabulated-list-revert (&rest ignored) @@ -351,7 +345,7 @@ of column descriptors." (defun tabulated-list-print-col (n col-desc x) "Insert a specified Tabulated List entry at point. -N is the column number, COL-DESC is a column descriptor \(see +N is the column number, COL-DESC is a column descriptor (see `tabulated-list-entries'), and X is the column number at point. Return the column number after insertion." ;; TODO: don't truncate to `width' if the next column is align-right |