1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-18 03:40:47 -08:00

Merge remote-tracking branch 'origin/master' into feature/package+vc

This commit is contained in:
Philip Kaludercic 2022-08-12 16:05:05 +02:00
commit 1823349e6a
No known key found for this signature in database
GPG key ID: F2C3CC513DB89F66
382 changed files with 8154 additions and 6180 deletions

View file

@ -1580,8 +1580,6 @@
:link '(custom-manual "(elisp)Advising Functions")
:group 'lisp)
(defconst ad-version "2.14")
;;;###autoload
(defcustom ad-redefinition-action 'warn
"Defines what to do with redefinitions during Advice de/activation.
@ -3250,6 +3248,9 @@ Use only in REAL emergencies."
(message "Oops! Left over advised function %S" function)
(ad-pop-advised-function function)))
(defconst ad-version "2.14")
(make-obsolete-variable 'ad-version 'emacs-version "29.1")
(provide 'advice)
;;; advice.el ends here

View file

@ -1,915 +0,0 @@
;;; autoload.el --- maintain autoloads in loaddefs.el -*- lexical-binding: t -*-
;; Copyright (C) 1991-1997, 2001-2022 Free Software Foundation, Inc.
;; Author: Roland McGrath <roland@gnu.org>
;; Keywords: maint
;; Package: emacs
;; This file is part of GNU Emacs.
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
;;; Commentary:
;; This code helps GNU Emacs maintainers keep the loaddefs.el file up to
;; date. It interprets magic cookies of the form ";;;###autoload" in
;; Lisp source files in various useful ways. To learn more, read the
;; source; if you're going to use this, you'd better be able to.
;; The functions in this file have been largely superseded by
;; loaddefs-gen.el.
;;; Code:
(require 'lisp-mode) ;for `doc-string-elt' properties.
(require 'lisp-mnt)
(require 'cl-lib)
(require 'loaddefs-gen)
;; This feels like it should be a defconst, but MH-E sets it to
;; ";;;###mh-autoload" for the autoloads that are to go into mh-loaddefs.el.
(defvar generate-autoload-cookie ";;;###autoload"
"Magic comment indicating the following form should be autoloaded.
Used by \\[update-file-autoloads]. This string should be
meaningless to Lisp (e.g., a comment).
This string is used:
\;;;###autoload
\(defun function-to-be-autoloaded () ...)
If this string appears alone on a line, the following form will be
read and an autoload made for it. If there is further text on the line,
that text will be copied verbatim to `generated-autoload-file'.")
(defvar autoload-excludes nil
"If non-nil, list of absolute file names not to scan for autoloads.")
(defconst generate-autoload-section-header "\f\n;;;### "
"String that marks the form at the start of a new file's autoload section.")
(defconst generate-autoload-section-trailer "\n;;;***\n"
"String which indicates the end of the section of autoloads for a file.")
(defconst generate-autoload-section-continuation ";;;;;; "
"String to add on each continuation of the section header form.")
;; In some ways it would be nicer to use a value that is recognizably
;; not a time-value, eg t, but that can cause issues if an older Emacs
;; that does not expect non-time-values loads the file.
(defconst autoload--non-timestamp '(0 0 0 0)
"Value to insert when `autoload-timestamps' is nil.")
(defvar autoload-timestamps nil ; experimental, see bug#22213
"Non-nil means insert a timestamp for each input file into the output.
We use these in incremental updates of the output file to decide
if we need to rescan an input file. If you set this to nil,
then we use the timestamp of the output file instead. As a result:
- for fixed inputs, the output will be the same every time
- incremental updates of the output file might not be correct if:
i) the timestamp of the output file cannot be trusted (at least
relative to that of the input files)
ii) any of the input files can be modified during the time it takes
to create the output
iii) only a subset of the input files are scanned
These issues are unlikely to happen in practice, and would arguably
represent bugs in the build system. Item iii) will happen if you
use a command like `update-file-autoloads', though, since it only
checks a single input file.")
(defvar autoload-modified-buffers) ;Dynamically scoped var.
(defalias 'make-autoload #'loaddefs-generate--make-autoload)
;; Forms which have doc-strings which should be printed specially.
;; A doc-string-elt property of ELT says that (nth ELT FORM) is
;; the doc-string in FORM.
;; Those properties are now set in lisp-mode.el.
(defun autoload-find-generated-file (file)
"Visit the autoload file for the current buffer, and return its buffer."
(let ((enable-local-variables :safe)
(enable-local-eval nil)
(find-file-hook nil)
(delay-mode-hooks t))
;; We used to use `raw-text' to read this file, but this causes
;; problems when the file contains non-ASCII characters.
(with-current-buffer (find-file-noselect
(autoload-ensure-file-writeable file))
(if (zerop (buffer-size)) (insert (autoload-rubric file nil t)))
(current-buffer))))
(defun autoload-generated-file (outfile)
"Return OUTFILE as an absolute name.
If `generated-autoload-file' is bound locally in the current
buffer, that is used instead, and it is expanded using the
default directory; otherwise, `source-directory'/lisp is used."
(expand-file-name (if (local-variable-p 'generated-autoload-file)
generated-autoload-file
outfile)
;; File-local settings of generated-autoload-file should
;; be interpreted relative to the file's location,
;; of course.
(if (not (local-variable-p 'generated-autoload-file))
(expand-file-name "lisp" source-directory))))
(defun autoload-read-section-header ()
"Read a section header form.
Since continuation lines have been marked as comments,
we must copy the text of the form and remove those comment
markers before we call `read'."
(save-match-data
(let ((beginning (point))
string)
(forward-line 1)
(while (looking-at generate-autoload-section-continuation)
(forward-line 1))
(setq string (buffer-substring beginning (point)))
(with-current-buffer (get-buffer-create " *autoload*")
(erase-buffer)
(insert string)
(goto-char (point-min))
(while (search-forward generate-autoload-section-continuation nil t)
(replace-match " "))
(goto-char (point-min))
(read (current-buffer))))))
(defvar autoload-print-form-outbuf nil
"Buffer which gets the output of `autoload-print-form'.")
(defun autoload-print-form (form)
"Print FORM such that `make-docfile' will find the docstrings.
The variable `autoload-print-form-outbuf' specifies the buffer to
put the output in."
(cond
;; If the form is a sequence, recurse.
((eq (car form) 'progn) (mapcar #'autoload-print-form (cdr form)))
;; Symbols at the toplevel are meaningless.
((symbolp form) nil)
(t
(let ((doc-string-elt (function-get (car-safe form) 'doc-string-elt))
(outbuf autoload-print-form-outbuf))
(if (and (numberp doc-string-elt) (stringp (nth doc-string-elt form)))
;; We need to hack the printing because the
;; doc-string must be printed specially for
;; make-docfile (sigh).
(let* ((p (nthcdr (1- doc-string-elt) form))
(elt (cdr p)))
(setcdr p nil)
(princ "\n(" outbuf)
(let ((print-escape-newlines t)
(print-escape-control-characters t)
(print-quoted t)
(print-escape-nonascii t))
(dolist (elt form)
(prin1 elt outbuf)
(princ " " outbuf)))
(princ "\"\\\n" outbuf)
(let ((begin (with-current-buffer outbuf (point))))
(princ (substring (prin1-to-string (car elt)) 1)
outbuf)
;; Insert a backslash before each ( that
;; appears at the beginning of a line in
;; the doc string.
(with-current-buffer outbuf
(save-excursion
(while (re-search-backward "\n[[(]" begin t)
(forward-char 1)
(insert "\\"))))
(if (null (cdr elt))
(princ ")" outbuf)
(princ " " outbuf)
(princ (substring (prin1-to-string (cdr elt)) 1)
outbuf))
(terpri outbuf)))
(let ((print-escape-newlines t)
(print-escape-control-characters t)
(print-quoted t)
(print-escape-nonascii t))
(print form outbuf)))))))
(defalias 'autoload-rubric #'loaddefs-generate--rubric)
(defvar autoload-ensure-writable nil
"Non-nil means `autoload-find-generated-file' makes existing file writable.")
;; Just in case someone tries to get you to overwrite a file that you
;; don't want to.
;;;###autoload
(put 'autoload-ensure-writable 'risky-local-variable t)
(defun autoload-ensure-file-writeable (file)
;; Probably pointless, but replaces the old AUTOGEN_VCS in lisp/Makefile,
;; which was designed to handle CVSREAD=1 and equivalent.
(and autoload-ensure-writable
(let ((modes (file-modes file)))
(if (and modes (zerop (logand modes #o0200)))
;; Ignore any errors here, and let subsequent attempts
;; to write the file raise any real error.
(ignore-errors (set-file-modes file (logior modes #o0200))))))
file)
(defun autoload-insert-section-header (outbuf autoloads load-name file time)
"Insert into buffer OUTBUF the section-header line for FILE.
The header line lists the file name, its \"load name\", its autoloads,
and the time the FILE was last updated (the time is inserted only
if `autoload-timestamps' is non-nil, otherwise a fixed fake time is inserted)."
;; (cl-assert ;Make sure we don't insert it in the middle of another section.
;; (save-excursion
;; (or (not (re-search-backward
;; (concat "\\("
;; (regexp-quote generate-autoload-section-header)
;; "\\)\\|\\("
;; (regexp-quote generate-autoload-section-trailer)
;; "\\)")
;; nil t))
;; (match-end 2))))
(insert generate-autoload-section-header)
(prin1 `(autoloads ,autoloads ,load-name ,file ,time)
outbuf)
(terpri outbuf)
;; Break that line at spaces, to avoid very long lines.
;; Make each sub-line into a comment.
(with-current-buffer outbuf
(save-excursion
(forward-line -1)
(while (not (eolp))
(move-to-column 64)
(skip-chars-forward "^ \n")
(or (eolp)
(insert "\n" generate-autoload-section-continuation))))))
(defun autoload-find-file (file)
"Fetch FILE and put it in a temp buffer. Return the buffer."
;; It is faster to avoid visiting the file.
(setq file (expand-file-name file))
(with-current-buffer (get-buffer-create " *autoload-file*")
(kill-all-local-variables)
(erase-buffer)
(setq buffer-undo-list t
buffer-read-only nil)
(delay-mode-hooks (emacs-lisp-mode))
(setq default-directory (file-name-directory file))
(insert-file-contents file nil)
(let ((enable-local-variables :safe)
(enable-local-eval nil))
(hack-local-variables))
(current-buffer)))
(defalias 'autoload-insert-section-header
#'loaddefs-generate--insert-section-header)
(defvar no-update-autoloads nil
"File local variable to prevent scanning this file for autoload cookies.")
(defalias 'autoload-file-load-name #'loaddefs-generate--file-load-name)
(defun generate-file-autoloads (file)
"Insert at point a loaddefs autoload section for FILE.
Autoloads are generated for defuns and defmacros in FILE
marked by `generate-autoload-cookie' (which see).
If FILE is being visited in a buffer, the contents of the buffer
are used.
Return non-nil in the case where no autoloads were added at point."
(interactive "fGenerate autoloads for file: ")
(let ((autoload-modified-buffers nil))
(autoload-generate-file-autoloads file (current-buffer) buffer-file-name)
autoload-modified-buffers))
(defconst autoload-def-prefixes-max-entries 5
"Target length of the list of definition prefixes per file.
If set too small, the prefixes will be too generic (i.e. they'll use little
memory, we'll end up looking in too many files when we need a particular
prefix), and if set too large, they will be too specific (i.e. they will
cost more memory use).")
(defconst autoload-def-prefixes-max-length 12
"Target size of definition prefixes.
Don't try to split prefixes that are already longer than that.")
(defalias 'autoload--make-defs-autoload #'loaddefs-generate--make-prefixes)
(defun autoload--setup-output (otherbuf outbuf absfile load-name output-file)
(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 output-file)
;; 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
(point-marker))))
(defun autoload--print-cookie-text (output-start load-name file)
(let ((standard-output (marker-buffer output-start)))
(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)
(defun autoload-generate-file-autoloads (file &optional outbuf outfile)
"Insert an autoload section for FILE in the appropriate buffer.
Autoloads are generated for defuns and defmacros in FILE
marked by `generate-autoload-cookie' (which see).
If FILE is being visited in a buffer, the contents of the buffer are used.
OUTBUF is the buffer in which the autoload statements should be inserted.
If OUTBUF is nil, the output will go to OUTFILE, unless there's a
buffer-local setting of `generated-autoload-file' in FILE.
Return non-nil if and only if FILE adds no autoloads to OUTFILE
\(or OUTBUF if OUTFILE is nil). The actual return value is
FILE's modification time."
;; Include the file name in any error messages
(condition-case err
(let (load-name
(print-length nil)
(print-level nil)
(float-output-format nil)
(visited (get-file-buffer file))
(otherbuf nil)
(absfile (expand-file-name file))
(defs '())
;; nil until we found a cookie.
output-start)
(when
(catch 'done
(with-current-buffer (or visited
;; It is faster to avoid visiting the file.
(autoload-find-file file))
;; Obey the no-update-autoloads file local variable.
(unless no-update-autoloads
(or noninteractive (message "Generating autoloads for %s..." file))
(setq load-name
(if (stringp generated-autoload-load-name)
generated-autoload-load-name
(autoload-file-load-name absfile outfile)))
;; FIXME? Comparing file-names for equality with just equal
;; is fragile, eg if one has an automounter prefix and one
;; does not, but both refer to the same physical file.
(when (and outfile
(not outbuf)
(not
(if (memq system-type '(ms-dos windows-nt))
(equal (downcase outfile)
(downcase (autoload-generated-file
outfile)))
(equal outfile (autoload-generated-file
outfile)))))
(setq otherbuf t))
(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 (autoload--setup-output
otherbuf outbuf absfile
load-name outfile))
(let ((standard-output (marker-buffer output-start))
(print-quoted t))
(princ `(push (purecopy
',(cons (intern package) version))
package--builtin-versions))
(princ "\n")))))
;; Do not insert autoload entries for excluded files.
(unless (member absfile autoload-excludes)
(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
(setq output-start (autoload--setup-output
otherbuf outbuf absfile
load-name outfile)))
(autoload--print-cookie-text output-start load-name file))
((= (following-char) ?\;)
;; Don't read the comment.
(forward-line 1))
(t
;; Avoid (defvar <foo>) by requiring a trailing space.
;; Also, ignore this prefix business
;; for ;;;###tramp-autoload and friends.
(when (and (equal generate-autoload-cookie ";;;###autoload")
(looking-at "(\\(def[^ ]+\\) ['(]*\\([^' ()\"\n]+\\)[\n \t]")
(not (member
(match-string 1)
autoload-ignored-definitions)))
(push (match-string-no-properties 2) defs))
(forward-sexp 1)
(forward-line 1)))))))
(when (and autoload-compute-prefixes defs)
;; This output needs to always go in the main loaddefs.el,
;; regardless of generated-autoload-file.
;; FIXME: the files that don't have autoload cookies but
;; do have definitions end up listed twice in loaddefs.el:
;; once for their register-definition-prefixes and once in
;; the list of "files without any autoloads".
(let ((form (autoload--make-defs-autoload defs load-name)))
(cond
((null form)) ;All defs obey the default rule, yay!
((not otherbuf)
(unless output-start
(setq output-start (autoload--setup-output
nil outbuf absfile load-name outfile)))
(let ((autoload-print-form-outbuf
(marker-buffer output-start)))
(autoload-print-form form)))
(t
(let* ((other-output-start
;; To force the output to go to the main loaddefs.el
;; rather than to generated-autoload-file,
;; there are two cases: if outbuf is non-nil,
;; then passing otherbuf=nil is enough, but if
;; outbuf is nil, that won't cut it, so we
;; locally bind generated-autoload-file.
(autoload--setup-output nil outbuf absfile load-name
outfile))
(autoload-print-form-outbuf
(marker-buffer other-output-start)))
(autoload-print-form form)
(with-current-buffer (marker-buffer other-output-start)
(save-excursion
;; Insert the section-header line which lists
;; the file name and which functions are in it, etc.
(goto-char other-output-start)
(let ((relfile (file-relative-name absfile)))
(autoload-insert-section-header
(marker-buffer other-output-start)
"actual autoloads are elsewhere" load-name relfile
(if autoload-timestamps
(file-attribute-modification-time
(file-attributes absfile))
autoload--non-timestamp))
(insert ";;; Generated autoloads from " relfile "\n")))
(insert generate-autoload-section-trailer)))))))
(when output-start
(let ((secondary-autoloads-file-buf
(if otherbuf (current-buffer))))
(with-current-buffer (marker-buffer output-start)
(cl-assert (> (point) output-start))
(save-excursion
;; Insert the section-header line which lists the file name
;; and which functions are in it, etc.
(goto-char output-start)
(let ((relfile (file-relative-name absfile)))
(autoload-insert-section-header
(marker-buffer output-start)
() 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
;; equal on two different systems and will change
;; less often than time-stamps, thus leading to fewer
;; unneeded changes causing spurious conflicts), but
;; using time-stamps is a very useful optimization,
;; so we use time-stamps for the main autoloads file
;; (loaddefs.el) where we have special ways to
;; circumvent the "random change problem", and MD5
;; checksum in secondary autoload files where we do
;; not need the time-stamp optimization because it is
;; already provided by the primary autoloads file.
(md5 secondary-autoloads-file-buf
;; We'd really want to just use
;; `emacs-internal' instead.
nil nil 'emacs-mule-unix)
(if autoload-timestamps
(file-attribute-modification-time
(file-attributes relfile))
autoload--non-timestamp)))
(insert ";;; Generated autoloads from " relfile "\n")))
(insert generate-autoload-section-trailer))))
(or noninteractive
(message "Generating autoloads for %s...done" file)))
(or visited
;; We created this buffer, so we should kill it.
(kill-buffer (current-buffer))))
(or (not output-start)
;; If the entries were added to some other buffer, then the file
;; doesn't add entries to OUTFILE.
otherbuf))
(file-attribute-modification-time (file-attributes absfile))))
(error
;; Probably unbalanced parens in forward-sexp. In that case, the
;; condition is scan-error, and the signal data includes point
;; where the error was found; we'd like to convert that to
;; line:col, but line-number-at-pos gets the wrong line in batch
;; mode for some reason.
;;
;; At least this gets the file name in the error message; the
;; developer can use goto-char to get to the error position.
(error "%s:0:0: error: %s: %s" file (car err) (cdr err)))
))
;; For parallel builds, to stop another process reading a half-written file.
(defun autoload--save-buffer ()
"Save current buffer to its file, atomically."
;; Similar to byte-compile-file.
(let* ((version-control 'never)
(tempfile (make-temp-file buffer-file-name))
(default-modes (default-file-modes))
(temp-modes (logand default-modes #o600))
(desired-modes (logand default-modes
(or (file-modes buffer-file-name) #o666)))
(kill-emacs-hook
(cons (lambda () (ignore-errors (delete-file tempfile)))
kill-emacs-hook)))
(unless (= temp-modes desired-modes)
(set-file-modes tempfile desired-modes 'nofollow))
(write-region (point-min) (point-max) tempfile nil 1)
(backup-buffer)
(rename-file tempfile buffer-file-name t))
(set-buffer-modified-p nil)
(set-visited-file-modtime)
(or noninteractive (message "Wrote %s" buffer-file-name)))
(defun autoload-save-buffers ()
(while autoload-modified-buffers
(with-current-buffer (pop autoload-modified-buffers)
(autoload--save-buffer))))
;; FIXME This command should be deprecated.
;; See https://debbugs.gnu.org/22213#41
;;;###autoload
(defun update-file-autoloads (file &optional save-after outfile)
"Update the autoloads for FILE.
If prefix arg SAVE-AFTER is non-nil, save the buffer too.
If FILE binds `generated-autoload-file' as a file-local variable,
autoloads are written into that file. Otherwise, the autoloads
file is determined by OUTFILE. If called interactively, prompt
for OUTFILE; if called from Lisp with OUTFILE nil, use the
existing value of `generated-autoload-file'.
Return FILE if there was no autoload cookie in it, else nil."
(interactive (list (read-file-name "Update autoloads for file: ")
current-prefix-arg
(read-file-name "Write autoload definitions to file: ")))
(setq outfile (or outfile generated-autoload-file))
(let* ((autoload-modified-buffers nil)
;; We need this only if the output file handles more than one input.
;; See https://debbugs.gnu.org/22213#38 and subsequent.
(autoload-timestamps t)
(no-autoloads (autoload-generate-file-autoloads
file nil
(if (local-variable-p 'generated-autoload-file)
generated-autoload-file
outfile))))
(if autoload-modified-buffers
(if save-after (autoload-save-buffers))
(if (called-interactively-p 'interactive)
(message "Autoload section for %s is up to date." file)))
(if no-autoloads file)))
(defun autoload-find-destination (file load-name output-file)
"Find the destination point of the current buffer's autoloads.
FILE is the file name of the current buffer.
LOAD-NAME is the name as it appears in the output.
Returns a buffer whose point is placed at the requested location.
Returns nil if the file's autoloads are up-to-date, otherwise
removes any prior now out-of-date autoload entries."
(catch 'up-to-date
(let* ((buf (current-buffer))
(existing-buffer (if buffer-file-name buf))
(output-file (autoload-generated-file output-file))
(output-time (if (file-exists-p output-file)
(file-attribute-modification-time
(file-attributes output-file))))
(found nil))
(with-current-buffer (autoload-find-generated-file output-file)
;; This is to make generated-autoload-file have Unix EOLs, so
;; that it is portable to all platforms.
(or (eq 0 (coding-system-eol-type buffer-file-coding-system))
(set-buffer-file-coding-system 'unix))
(or (> (buffer-size) 0)
(error "Autoloads file %s lacks boilerplate" buffer-file-name))
(or (file-writable-p buffer-file-name)
(error "Autoloads file %s is not writable" buffer-file-name))
(widen)
(goto-char (point-min))
;; Look for the section for LOAD-NAME.
(while (and (not found)
(search-forward generate-autoload-section-header nil t))
(let ((form (autoload-read-section-header)))
(cond ((string= (nth 2 form) load-name)
;; We found the section for this file.
;; Check if it is up to date.
(let ((begin (match-beginning 0))
(last-time (nth 4 form))
(file-time (file-attribute-modification-time
(file-attributes file))))
(if (and (or (null existing-buffer)
(not (buffer-modified-p existing-buffer)))
(cond
;; FIXME? Arguably we should throw a
;; user error, or some kind of warning,
;; if we were called from update-file-autoloads,
;; which can update only a single input file.
;; It's not appropriate to use the output
;; file modtime in such a case,
;; if there are multiple input files
;; contributing to the output.
((and output-time
(member last-time
(list t autoload--non-timestamp)))
(not (time-less-p output-time file-time)))
;; last-time is the time-stamp (specifying
;; the last time we looked at the file) and
;; the file hasn't been changed since.
((listp last-time)
(not (time-less-p last-time file-time)))
;; last-time is an MD5 checksum instead.
((stringp last-time)
(equal last-time
(md5 buf nil nil 'emacs-mule)))))
(throw 'up-to-date nil)
(autoload-remove-section begin)
(setq found t))))
((string< load-name (nth 2 form))
;; We've come to a section alphabetically later than
;; LOAD-NAME. We assume the file is in order and so
;; there must be no section for LOAD-NAME. We will
;; insert one before the section here.
(goto-char (match-beginning 0))
(setq found t)))))
(or found
(progn
;; No later sections in the file. Put before the last page.
(goto-char (point-max))
(search-backward "\f" nil t)))
(unless (memq (current-buffer) autoload-modified-buffers)
(push (current-buffer) autoload-modified-buffers))
(current-buffer)))))
(defun autoload-remove-section (begin)
(goto-char begin)
(search-forward generate-autoload-section-trailer)
(delete-region begin (point)))
;;;###autoload
(defun update-directory-autoloads (&rest dirs)
"Update autoload definitions for Lisp files in the directories DIRS.
In an interactive call, you must give one argument, the name of a
single directory. In a call from Lisp, you can supply multiple
directories as separate arguments, but this usage is discouraged.
The function does NOT recursively descend into subdirectories of the
directory or directories specified.
In an interactive call, prompt for a default output file for the
autoload definitions. When called from Lisp, use the existing
value of `generated-autoload-file'. If any Lisp file binds
`generated-autoload-file' as a file-local variable, write its
autoloads into the specified file instead."
(declare (obsolete make-directory-autoloads "28.1"))
(interactive "DUpdate autoloads from directory: ")
(make-directory-autoloads
dirs
(if (called-interactively-p 'interactive)
(read-file-name "Write autoload definitions to file: ")
generated-autoload-file)))
;;;###autoload
(defun make-directory-autoloads (dir output-file)
"Update autoload definitions for Lisp files in the directories DIRS.
DIR can be either a single directory or a list of
directories. (The latter usage is discouraged.)
The autoloads will be written to OUTPUT-FILE. If any Lisp file
binds `generated-autoload-file' as a file-local variable, write
its autoloads into the specified file instead.
The function does NOT recursively descend into subdirectories of the
directory or directories specified."
(interactive "DUpdate autoloads from directory: \nFWrite to file: ")
(let* ((files-re (let ((tmp nil))
(dolist (suf (get-load-suffixes))
;; We don't use module-file-suffix below because
;; we don't want to depend on whether Emacs was
;; built with or without modules support, nor
;; what is the suffix for the underlying OS.
(unless (string-match "\\.\\(elc\\|so\\|dll\\)" suf)
(push suf tmp)))
(concat "\\`[^=.].*" (regexp-opt tmp t) "\\'")))
(files (apply #'nconc
(mapcar (lambda (d)
(directory-files (expand-file-name d)
t files-re))
(if (consp dir) dir (list dir)))))
(done ()) ;Files processed; to remove duplicates.
(changed nil) ;Non-nil if some change occurred.
(last-time)
;; Files with no autoload cookies or whose autoloads go to other
;; files because of file-local autoload-generated-file settings.
(no-autoloads nil)
;; Ensure that we don't do odd things when putting the doc
;; strings into the autoloads file.
(left-margin 0)
(autoload-modified-buffers nil)
(output-time
(and (file-exists-p output-file)
(file-attribute-modification-time
(file-attributes output-file)))))
(with-current-buffer (autoload-find-generated-file output-file)
(save-excursion
;; Canonicalize file names and remove the autoload file itself.
(setq files (delete (file-relative-name buffer-file-name)
(mapcar #'file-relative-name files)))
(goto-char (point-min))
(while (search-forward generate-autoload-section-header nil t)
(let* ((form (autoload-read-section-header))
(file (nth 3 form)))
(cond ((and (consp file) (stringp (car file)))
;; This is a list of files that have no autoload cookies.
;; There shouldn't be more than one such entry.
;; Remove the obsolete section.
(autoload-remove-section (match-beginning 0))
(setq last-time (nth 4 form))
(if (member last-time (list t autoload--non-timestamp))
(setq last-time output-time))
(dolist (file file)
(let ((file-time (file-attribute-modification-time
(file-attributes file))))
(when (and file-time
(not (time-less-p last-time file-time)))
;; file unchanged
(push file no-autoloads)
(setq files (delete file files))))))
((not (stringp file)))
((or (not (file-exists-p file))
;; Remove duplicates as well, just in case.
(member file done))
;; Remove the obsolete section.
(setq changed t)
(autoload-remove-section (match-beginning 0)))
((not (time-less-p (let ((oldtime (nth 4 form)))
(if (member oldtime
(list
t autoload--non-timestamp))
output-time
oldtime))
(file-attribute-modification-time
(file-attributes file))))
;; File hasn't changed.
nil)
(t
(setq changed t)
(autoload-remove-section (match-beginning 0))
(if (autoload-generate-file-autoloads
;; Passing `current-buffer' makes it insert at point.
file (current-buffer) buffer-file-name)
(push file no-autoloads))))
(push file done)
(setq files (delete file files)))))
;; Elements remaining in FILES have no existing autoload sections yet.
(let ((no-autoloads-time (or last-time '(0 0 0 0)))
(progress (make-progress-reporter
(byte-compile-info
(concat "Scraping files for "
(file-relative-name output-file)))
0 (length files) nil 10))
(file-count 0)
file-time)
(dolist (file files)
(progress-reporter-update progress (setq file-count (1+ file-count)))
(cond
;; Passing nil as second argument forces
;; autoload-generate-file-autoloads to look for the right
;; spot where to insert each autoloads section.
((setq file-time
(autoload-generate-file-autoloads file nil buffer-file-name))
(push file no-autoloads)
(if (time-less-p no-autoloads-time file-time)
(setq no-autoloads-time file-time)))
(t (setq changed t))))
(progress-reporter-done progress)
(when no-autoloads
;; Sort them for better readability.
(setq no-autoloads (sort no-autoloads 'string<))
;; Add the `no-autoloads' section.
(goto-char (point-max))
(search-backward "\f" nil t)
(autoload-insert-section-header
(current-buffer) nil nil
;; Filter out the other loaddefs files, because it makes
;; the list unstable (and leads to spurious changes in
;; ldefs-boot.el) since the loaddef files can be created in
;; any order.
(seq-filter (lambda (file)
(not (string-match-p "[/-]loaddefs.el" file)))
no-autoloads)
(if autoload-timestamps
no-autoloads-time
autoload--non-timestamp))
(insert generate-autoload-section-trailer)))
;; Don't modify the file if its content has not been changed, so `make'
;; dependencies don't trigger unnecessarily.
(if (not changed)
(set-buffer-modified-p nil)
(autoload--save-buffer))
;; In case autoload entries were added to other files because of
;; file-local autoload-generated-file settings.
(autoload-save-buffers))))
(defun batch-update-autoloads--summary (strings)
(let ((message ""))
(while strings
(when (> (length (concat message " " (car strings))) 64)
(byte-compile-info (concat message " ...") t "SCRAPE")
(setq message ""))
(setq message (if (zerop (length message))
(car strings)
(concat message " " (car strings))))
(setq strings (cdr strings)))
(when (> (length message) 0)
(byte-compile-info message t "SCRAPE"))))
;;;###autoload
(defun batch-update-autoloads ()
"Update loaddefs.el autoloads in batch mode.
Calls `update-directory-autoloads' on the command line arguments.
Definitions are written to `generated-autoload-file' (which
should be non-nil)."
;; For use during the Emacs build process only.
;; Exclude those files that are preloaded on ALL platforms.
;; These are the ones in loadup.el where "(load" is at the start
;; of the line (crude, but it works).
(unless autoload-excludes
(let ((default-directory (file-name-directory generated-autoload-file))
file)
(when (file-readable-p "loadup.el")
(with-temp-buffer
(insert-file-contents "loadup.el")
(while (re-search-forward "^(load \"\\([^\"]+\\)\"" nil t)
(setq file (match-string 1))
(or (string-match "\\.el\\'" file)
(setq file (format "%s.el" file)))
(or (string-match "\\`site-" file)
(push (expand-file-name file) autoload-excludes)))))))
(let ((args command-line-args-left))
(batch-update-autoloads--summary args)
(setq command-line-args-left nil)
(make-directory-autoloads args generated-autoload-file)))
(provide 'autoload)
;;; autoload.el ends here

View file

@ -1747,10 +1747,10 @@ See Info node `(elisp) Integer Basics'."
byte-goto-if-not-nil-else-pop))
(defconst byte-after-unbind-ops
'(byte-constant byte-dup
'(byte-constant byte-dup byte-stack-ref byte-stack-set byte-discard
byte-symbolp byte-consp byte-stringp byte-listp byte-numberp byte-integerp
byte-eq byte-not
byte-cons byte-list1 byte-list2 ; byte-list3 byte-list4
byte-cons byte-list1 byte-list2 byte-list3 byte-list4 byte-listN
byte-interactive-p)
;; How about other side-effect-free-ops? Is it safe to move an
;; error invocation (such as from nth) out of an unwind-protect?
@ -1762,7 +1762,8 @@ See Info node `(elisp) Integer Basics'."
(defconst byte-compile-side-effect-and-error-free-ops
'(byte-constant byte-dup byte-symbolp byte-consp byte-stringp byte-listp
byte-integerp byte-numberp byte-eq byte-equal byte-not byte-car-safe
byte-cdr-safe byte-cons byte-list1 byte-list2 byte-point byte-point-max
byte-cdr-safe byte-cons byte-list1 byte-list2 byte-list3 byte-list4
byte-listN byte-point byte-point-max
byte-point-min byte-following-char byte-preceding-char
byte-current-column byte-eolp byte-eobp byte-bolp byte-bobp
byte-current-buffer byte-stack-ref))
@ -2113,13 +2114,15 @@ If FOR-EFFECT is non-nil, the return value is assumed to be of no importance."
(setcar (cdr rest) lap0)
(setq keep-going t))
;;
;; varbind-X unbind-N --> discard unbind-(N-1)
;; save-excursion unbind-N --> unbind-(N-1)
;; save-restriction unbind-N --> unbind-(N-1)
;; varbind-X unbind-N --> discard unbind-(N-1)
;; save-excursion unbind-N --> unbind-(N-1)
;; save-restriction unbind-N --> unbind-(N-1)
;; save-current-buffer unbind-N --> unbind-(N-1)
;;
((and (eq 'byte-unbind (car lap1))
(memq (car lap0) '(byte-varbind byte-save-excursion
byte-save-restriction))
byte-save-restriction
byte-save-current-buffer))
(< 0 (cdr lap1)))
(if (zerop (setcdr lap1 (1- (cdr lap1))))
(delq lap1 rest))

View file

@ -236,6 +236,20 @@ The return value of this function is not used."
(list 'function-put (list 'quote f)
''command-modes (list 'quote val))))
(defalias 'byte-run--set-interactive-args
#'(lambda (f args &rest val)
(setq args (remove '&optional (remove '&rest args)))
(list 'function-put (list 'quote f)
''interactive-args
(list
'quote
(mapcar
(lambda (elem)
(cons
(seq-position args (car elem))
(cadr elem)))
val)))))
;; Add any new entries to info node `(elisp)Declare Form'.
(defvar defun-declarations-alist
(list
@ -255,7 +269,8 @@ If `error-free', drop calls even if `byte-compile-delete-errors' is nil.")
(list 'indent #'byte-run--set-indent)
(list 'speed #'byte-run--set-speed)
(list 'completion #'byte-run--set-completion)
(list 'modes #'byte-run--set-modes))
(list 'modes #'byte-run--set-modes)
(list 'interactive-args #'byte-run--set-interactive-args))
"List associating function properties to their macro expansion.
Each element of the list takes the form (PROP FUN) where FUN is
a function. For each (PROP . VALUES) in a function's declaration,

View file

@ -767,7 +767,7 @@ Each element is (INDEX . VALUE)")
(byte-defop 122 0 byte-char-syntax)
(byte-defop 123 -1 byte-buffer-substring)
(byte-defop 124 -1 byte-delete-region)
(byte-defop 125 -2 byte-narrow-to-region)
(byte-defop 125 -1 byte-narrow-to-region)
(byte-defop 126 1 byte-widen)
(byte-defop 127 0 byte-end-of-line)
@ -1760,7 +1760,7 @@ It is too wide if it has any lines longer than the largest of
kind name col))
;; There's a "naked" ' character before a symbol/list, so it
;; should probably be quoted with \=.
(when (string-match-p "\\( \"\\|[ \t]\\|^\\)'[a-z(]" docs)
(when (string-match-p "\\( [\"#]\\|[ \t]\\|^\\)'[a-z(]" docs)
(byte-compile-warn-x
name "%s%sdocstring has wrong usage of unescaped single quotes (use \\= or different quoting)"
kind name))
@ -2416,8 +2416,8 @@ Call from the source buffer."
(defun byte-compile-output-file-form (form)
;; Write the given form to the output buffer, being careful of docstrings
;; in defvar, defvaralias, defconst, autoload and
;; custom-declare-variable because make-docfile is so amazingly stupid.
;; (for `byte-compile-dynamic-docstrings') in defvar, defvaralias,
;; defconst, autoload, and custom-declare-variable.
;; defalias calls are output directly by byte-compile-file-form-defmumble;
;; it does not pay to first build the defalias in defmumble and then parse
;; it here.
@ -2463,21 +2463,9 @@ list that represents a doc string reference.
(let (position
(print-symbols-bare t)) ; Possibly redundant binding.
;; Insert the doc string, and make it a comment with #@LENGTH.
(and (>= (nth 1 info) 0)
dynamic-docstrings
(progn
;; Make the doc string start at beginning of line
;; for make-docfile's sake.
(insert "\n")
(setq position
(byte-compile-output-as-comment
(nth (nth 1 info) form) nil))
;; If the doc string starts with * (a user variable),
;; negate POSITION.
(if (and (stringp (nth (nth 1 info) form))
(> (length (nth (nth 1 info) form)) 0)
(eq (aref (nth (nth 1 info) form) 0) ?*))
(setq position (- position)))))
(when (and (>= (nth 1 info) 0) dynamic-docstrings)
(setq position (byte-compile-output-as-comment
(nth (nth 1 info) form) nil)))
(let ((print-continuous-numbering t)
print-number-table
@ -2604,8 +2592,8 @@ list that represents a doc string reference.
(t
(byte-compile-keep-pending form)))))
;; Functions and variables with doc strings must be output separately,
;; so make-docfile can recognize them. Most other things can be output
;; Functions and variables with doc strings must be output specially,
;; for `byte-compile-dynamic-docstrings'. Most other things can be output
;; as byte-code.
(put 'autoload 'byte-hunk-handler 'byte-compile-file-form-autoload)
@ -3845,7 +3833,7 @@ If it is nil, then the handler is \"byte-compile-SYMBOL.\""
(byte-defop-compiler setcdr 2)
(byte-defop-compiler buffer-substring 2)
(byte-defop-compiler delete-region 2)
(byte-defop-compiler narrow-to-region 2-3)
(byte-defop-compiler narrow-to-region 2)
(byte-defop-compiler (% byte-rem) 2)
(byte-defop-compiler aset 3)
@ -5004,7 +4992,7 @@ binding slots have been popped."
;;
;; FIXME: we also use this hunk-handler to implement the function's
;; dynamic docstring feature (via byte-compile-file-form-defmumble).
;; We should actually implement it (more elegantly) in
;; We should probably actually implement it (more elegantly) in
;; byte-compile-lambda so it applies to all lambdas. We did it here
;; so the resulting .elc format was recognizable by make-docfile,
;; but since then we stopped using DOC for the docstrings of

View file

@ -1,6 +1,6 @@
;;; checkdoc.el --- check documentation strings for style requirements -*- lexical-binding:t -*-
;; Copyright (C) 1997-1998, 2001-2022 Free Software Foundation, Inc.
;; Copyright (C) 1997-2022 Free Software Foundation, Inc.
;; Author: Eric M. Ludlam <zappo@gnu.org>
;; Old-Version: 0.6.2
@ -248,7 +248,7 @@ with these words enabled."
;;;###autoload(put 'checkdoc-spellcheck-documentation-flag 'safe-local-variable #'booleanp)
(defvar checkdoc-ispell-lisp-words
'("alist" "emacs" "etags" "keymap" "paren" "regexp" "sexp" "xemacs")
'("alist" "emacs" "etags" "keymap" "paren" "regexp" "sexp")
"List of words that are correct when spell-checking Lisp documentation.")
;;;###autoload(put 'checkdoc-ispell-list-words 'safe-local-variable #'checkdoc-list-of-strings-p)
@ -1357,23 +1357,6 @@ checking of documentation strings.
checkdoc-common-verbs-wrong-voice "\\|")
"\\)\\>"))))
;; Profiler says this is not yet faster than just calling assoc
;;(defun checkdoc-word-in-alist-vector (word vector)
;; "Check to see if WORD is in the car of an element of VECTOR.
;;VECTOR must be sorted. The CDR should be a replacement. Since the
;;word list is getting bigger, it is time for a quick bisecting search."
;; (let ((max (length vector)) (min 0) i
;; (found nil) (fw nil))
;; (setq i (/ max 2))
;; (while (and (not found) (/= min max))
;; (setq fw (car (aref vector i)))
;; (cond ((string= word fw) (setq found (cdr (aref vector i))))
;; ((string< word fw) (setq max i))
;; (t (setq min i)))
;; (setq i (/ (+ max min) 2))
;; )
;; found))
;;; Checking engines
;;
(defun checkdoc-this-string-valid (&optional take-notes)
@ -2360,8 +2343,6 @@ News agents may remove it"
;;; Comment checking engine
;;
(defvar generate-autoload-cookie)
(defun checkdoc-file-comments-engine ()
"Return a message list if this file does not match the Emacs standard.
This checks for style only, such as the first line, Commentary:,
@ -2862,8 +2843,6 @@ function called to create the messages."
(custom-add-option 'emacs-lisp-mode-hook 'checkdoc-minor-mode)
;; Obsolete
(define-obsolete-function-alias 'checkdoc-run-hooks
#'run-hook-with-args-until-success "28.1")
(defvar checkdoc-version "0.6.2"

View file

@ -372,8 +372,8 @@ SEQ, this is like `mapcar'. With several, it is like the Common Lisp
(cl--defalias 'cl-second 'cadr)
(cl--defalias 'cl-rest 'cdr)
(cl--defalias 'cl-third 'cl-caddr "Return the third element of the list X.")
(cl--defalias 'cl-fourth 'cl-cadddr "Return the fourth element of the list X.")
(cl--defalias 'cl-third #'caddr "Return the third element of the list X.")
(cl--defalias 'cl-fourth #'cadddr "Return the fourth element of the list X.")
(defsubst cl-fifth (x)
"Return the fifth element of the list X."

View file

@ -527,7 +527,7 @@ its argument list allows full Common Lisp conventions."
(while (and (eq (car args) '&aux) (pop args))
(while (and args (not (memq (car args) cl--lambda-list-keywords)))
(if (consp (car args))
(if (and cl--bind-enquote (cl-cadar args))
(if (and cl--bind-enquote (cadar args))
(cl--do-arglist (caar args)
`',(cadr (pop args)))
(cl--do-arglist (caar args) (cadr (pop args))))
@ -612,7 +612,7 @@ its argument list allows full Common Lisp conventions."
(if (eq ?_ (aref name 0))
(setq name (substring name 1)))
(intern (format ":%s" name)))))
(varg (if (consp (car arg)) (cl-cadar arg) (car arg)))
(varg (if (consp (car arg)) (cadar arg) (car arg)))
(def (if (cdr arg) (cadr arg)
;; The ordering between those two or clauses is
;; irrelevant, since in practice only one of the two
@ -1339,7 +1339,7 @@ For more details, see Info node `(cl)Loop Facility'.
(temp-idx
(if (eq (car cl--loop-args) 'using)
(if (and (= (length (cadr cl--loop-args)) 2)
(eq (cl-caadr cl--loop-args) 'index))
(eq (caadr cl--loop-args) 'index))
(cadr (cl--pop2 cl--loop-args))
(error "Bad `using' clause"))
(make-symbol "--cl-idx--"))))
@ -1370,8 +1370,8 @@ For more details, see Info node `(cl)Loop Facility'.
(other
(if (eq (car cl--loop-args) 'using)
(if (and (= (length (cadr cl--loop-args)) 2)
(memq (cl-caadr cl--loop-args) hash-types)
(not (eq (cl-caadr cl--loop-args) word)))
(memq (caadr cl--loop-args) hash-types)
(not (eq (caadr cl--loop-args) word)))
(cadr (cl--pop2 cl--loop-args))
(error "Bad `using' clause"))
(make-symbol "--cl-var--"))))
@ -1433,8 +1433,8 @@ For more details, see Info node `(cl)Loop Facility'.
(other
(if (eq (car cl--loop-args) 'using)
(if (and (= (length (cadr cl--loop-args)) 2)
(memq (cl-caadr cl--loop-args) key-types)
(not (eq (cl-caadr cl--loop-args) word)))
(memq (caadr cl--loop-args) key-types)
(not (eq (caadr cl--loop-args) word)))
(cadr (cl--pop2 cl--loop-args))
(error "Bad `using' clause"))
(make-symbol "--cl-var--"))))
@ -1656,7 +1656,7 @@ If BODY is `setq', then use SPECS for assignments rather than for bindings."
(let ((temps nil) (new nil))
(when par
(let ((p specs))
(while (and p (or (symbolp (car-safe (car p))) (null (cl-cadar p))))
(while (and p (or (symbolp (car-safe (car p))) (null (cadar p))))
(setq p (cdr p)))
(when p
(setq par nil)
@ -1731,7 +1731,7 @@ such that COMBO is equivalent to (and . CLAUSES)."
(setq clauses (cons (nconc (butlast (car clauses))
(if (eq (car-safe (cadr clauses))
'progn)
(cl-cdadr clauses)
(cdadr clauses)
(list (cadr clauses))))
(cddr clauses)))
;; A final (progn ,@A t) is moved outside of the `and'.
@ -2563,9 +2563,9 @@ values. For compatibility, (cl-values A B C) is a synonym for (list A B C).
(defun cl--optimize (f _args &rest qualities)
"Serve `cl-optimize' in function declarations.
Example:
(defun foo (x)
(declare (cl-optimize (speed 3) (safety 0)))
x)"
(defun foo (x)
(declare (cl-optimize (speed 3) (safety 0)))
x)"
;; FIXME this should make use of `cl--declare-stack' but I suspect
;; this mechanism should be reviewed first.
(cl-loop for (qly val) in qualities
@ -2613,7 +2613,7 @@ Example:
((and (eq (car-safe spec) 'warn) (boundp 'byte-compile-warnings))
(while (setq spec (cdr spec))
(if (consp (car spec))
(if (eq (cl-cadar spec) 0)
(if (eq (cadar spec) 0)
(byte-compile-disable-warning (caar spec))
(byte-compile-enable-warning (caar spec)))))))
nil)
@ -3093,9 +3093,9 @@ To see the documentation for a defined struct type, use
(t `(and (consp cl-x)
(memq (nth ,pos cl-x) ,tag-symbol))))))
pred-check (and pred-form (> safety 0)
(if (and (eq (cl-caadr pred-form) 'vectorp)
(if (and (eq (caadr pred-form) 'vectorp)
(= safety 1))
(cons 'and (cl-cdddr pred-form))
(cons 'and (cdddr pred-form))
`(,predicate cl-x))))
(when pred-form
(push `(,defsym ,predicate (cl-x)

View file

@ -1915,7 +1915,10 @@ and the annotation emission."
(byte-char-syntax auto)
(byte-buffer-substring auto)
(byte-delete-region auto)
(byte-narrow-to-region auto)
(byte-narrow-to-region
(comp-emit-set-call (comp-call 'narrow-to-region
(comp-slot)
(comp-slot+1))))
(byte-widen
(comp-emit-set-call (comp-call 'widen)))
(byte-end-of-line auto)

View file

@ -864,7 +864,7 @@ marker. The needed data will then come from property
(defun edebug-read-special (stream)
"Read from STREAM a Lisp object beginning with #.
Turn #'thing into (function thing) and handle the read syntax for
Turn #\\='thing into (function thing) and handle the read syntax for
circular objects. Let `read' read everything else."
(catch 'return
(forward-char 1)

View file

@ -381,7 +381,6 @@ Also store it in `eldoc-last-message' and return that value."
(defun eldoc-display-message-no-interference-p ()
"Return nil if displaying a message would cause interference."
(not (or executing-kbd-macro
(bound-and-true-p edebug-active)
;; The following configuration shows "Matches..." in the
;; echo area when point is after a closing bracket, which
;; conflicts with eldoc.

View file

@ -1692,7 +1692,7 @@ test packages depend on each other, it might be helpful.")
(string-match-p "^Running 0 tests" logfile-contents))
(insert (format " <testsuite id=\"%s\" name=\"%s\" tests=\"1\" errors=\"1\" failures=\"0\" skipped=\"0\" time=\"0\" timestamp=\"%s\">\n"
id test-report
(ert--format-time-iso8601 (current-time))))
(ert--format-time-iso8601 nil)))
(insert (format " <testcase name=\"Test report missing %s\" status=\"error\" time=\"0\">\n"
(file-name-nondirectory test-report)))
(insert (format " <error message=\"Test report missing %s\" type=\"error\">\n"

View file

@ -131,7 +131,6 @@
(defun Helper-describe-bindings ()
"Describe local key bindings of current mode."
(interactive)
(message "Making binding list...")
(save-window-excursion (describe-bindings))
(Helper-help-scroller))

View file

@ -728,30 +728,62 @@ font-lock keywords will not be case sensitive."
len))))
(defun lisp-current-defun-name ()
"Return the name of the defun at point, or nil."
"Return the name of the defun at point.
If there is no defun at point, return the first symbol from the
top-level form. If there is no top-level form, return nil.
(\"defun\" here means \"form that defines something\", and is
decided heuristically.)"
(save-excursion
(let ((location (point)))
(let ((location (point))
name)
;; If we are now precisely at the beginning of a defun, make sure
;; beginning-of-defun finds that one rather than the previous one.
(or (eobp) (forward-char 1))
(unless (eobp)
(forward-char 1))
(beginning-of-defun)
;; Make sure we are really inside the defun found, not after it.
(when (and (looking-at "\\s(")
(progn (end-of-defun)
(< location (point)))
(progn (forward-sexp -1)
(>= location (point))))
(if (looking-at "\\s(")
(forward-char 1))
;; Skip the defining construct name, typically "defun" or
(when (and (looking-at "(")
(progn
(end-of-defun)
(< location (point)))
(progn
(forward-sexp -1)
(>= location (point))))
(when (looking-at "(")
(forward-char 1))
;; Read the defining construct name, typically "defun" or
;; "defvar".
(forward-sexp 1)
;; The second element is usually a symbol being defined. If it
;; is not, use the first symbol in it.
(skip-chars-forward " \t\n'(")
(buffer-substring-no-properties (point)
(progn (forward-sexp 1)
(point)))))))
(let ((symbol (ignore-errors (read (current-buffer)))))
(when (and symbol (not (symbolp symbol)))
(setq symbol nil))
;; If there's an edebug spec, use that to determine what the
;; name is.
(when symbol
(let ((spec (get symbol 'edebug-form-spec)))
(save-excursion
(when (and (eq (car-safe spec) '&define)
(memq 'name spec))
(pop spec)
(while (and spec (not name))
(let ((candidate (ignore-errors (read (current-buffer)))))
(when (eq (pop spec) 'name)
(setq name candidate
spec nil))))))))
;; We didn't have an edebug spec (or couldn't find the
;; name). If the symbol starts with \"def\", then it's
;; likely that the next symbol is the name.
(when (and (not name)
(string-match-p "\\(\\`\\|-\\)def" (symbol-name symbol)))
(when-let ((candidate (ignore-errors (read (current-buffer)))))
(cond
((symbolp candidate)
(setq name candidate))
((and (consp candidate)
(symbolp (car (delete 'quote candidate))))
(setq name (car (delete 'quote candidate)))))))
(when-let ((result (or name symbol)))
(symbol-name result)))))))
(defvar-keymap lisp-mode-shared-map
:doc "Keymap for commands shared by all sorts of Lisp modes."

View file

@ -507,6 +507,11 @@ It is called with no argument, right after calling `beginning-of-defun-raw'.
So the function can assume that point is at the beginning of the defun body.
It should move point to the first position after the defun.")
(defvar end-of-defun-moves-to-eol t
"Whether `end-of-defun' moves to eol before doing anything else.
Set this to nil if this movement adversely affects the buffer's
major mode's decisions about context.")
(defun buffer-end (arg)
"Return the \"far end\" position of the buffer, in direction ARG.
If ARG is positive, that's the end of the buffer.
@ -538,7 +543,9 @@ report errors as appropriate for this kind of usage."
(push-mark))
(if (or (null arg) (= arg 0)) (setq arg 1))
(let ((pos (point))
(beg (progn (end-of-line 1) (beginning-of-defun-raw 1) (point)))
(beg (progn (when end-of-defun-moves-to-eol
(end-of-line 1))
(beginning-of-defun-raw 1) (point)))
(skip (lambda ()
;; When comparing point against pos, we want to consider that
;; if point was right after the end of the function, it's

View file

@ -50,17 +50,27 @@ prefix, that will not be registered. But all other prefixes will
be included.")
(put 'autoload-compute-prefixes 'safe-local-variable #'booleanp)
(defvar no-update-autoloads nil
"File local variable to prevent scanning this file for autoload cookies.")
(defvar autoload-ignored-definitions
'("define-obsolete-function-alias"
"define-obsolete-variable-alias"
"define-category" "define-key"
"define-category"
"define-key" "define-key-after" "define-keymap"
"defgroup" "defface" "defadvice"
"def-edebug-spec"
;; Hmm... this is getting ugly:
"define-widget"
"define-erc-module"
"define-erc-response-handler"
"defun-rcirc-command")
"defun-rcirc-command"
"define-short-documentation-group"
"def-edebug-elem-spec"
"defvar-mode-local"
"defcustom-mode-local-semantic-dependency-system-include-path"
"define-ibuffer-column"
"define-ibuffer-sorter")
"List of strings naming definitions to ignore for prefixes.
More specifically those definitions will not be considered for the
`register-definition-prefixes' call.")
@ -117,6 +127,15 @@ scanning for autoloads and will be in the `load-path'."
(substring name 0 (match-beginning 0))
name)))
(defun loaddefs-generate--shorten-autoload (form)
"Remove optional nil elements from an `autoload' form."
(take (max (- (length form)
(seq-position (reverse form) nil
(lambda (e1 e2)
(not (eq e1 e2)))))
3)
form))
(defun loaddefs-generate--make-autoload (form file &optional expansion)
"Turn FORM into an autoload or defvar for source file FILE.
Returns nil if FORM is not a special autoload form (i.e. a function definition
@ -155,8 +174,8 @@ expression, in which case we want to handle forms differently."
;; Add the usage form at the end where describe-function-1
;; can recover it.
(when (consp args) (setq doc (help-add-fundoc-usage doc args)))
;; (message "autoload of %S" (nth 1 form))
`(autoload ,(nth 1 form) ,file ,doc ,interactive ,type)))
(loaddefs-generate--shorten-autoload
`(autoload ,(nth 1 form) ,file ,doc ,interactive ,type))))
((and expansion (memq car '(progn prog1)))
(let ((end (memq :autoload-end form)))
@ -210,22 +229,23 @@ expression, in which case we want to handle forms differently."
;; can recover it.
(when (listp args) (setq doc (help-add-fundoc-usage doc args)))
;; `define-generic-mode' quotes the name, so take care of that
`(autoload ,(if (listp name) name (list 'quote name))
,file ,doc
,(or (and (memq car '(define-skeleton define-derived-mode
define-generic-mode
easy-mmode-define-global-mode
define-global-minor-mode
define-globalized-minor-mode
easy-mmode-define-minor-mode
define-minor-mode))
t)
(and (eq (car-safe (car body)) 'interactive)
;; List of modes or just t.
(or (if (nthcdr 1 (car body))
(list 'quote (nthcdr 1 (car body)))
t))))
,(if macrop ''macro nil))))
(loaddefs-generate--shorten-autoload
`(autoload ,(if (listp name) name (list 'quote name))
,file ,doc
,(or (and (memq car '(define-skeleton define-derived-mode
define-generic-mode
easy-mmode-define-global-mode
define-global-minor-mode
define-globalized-minor-mode
easy-mmode-define-minor-mode
define-minor-mode))
t)
(and (eq (car-safe (car body)) 'interactive)
;; List of modes or just t.
(or (if (nthcdr 1 (car body))
(list 'quote (nthcdr 1 (car body)))
t))))
,(if macrop ''macro nil)))))
;; For defclass forms, use `eieio-defclass-autoload'.
((eq car 'defclass)
@ -447,7 +467,7 @@ don't include."
(let ((prefs nil))
;; Avoid (defvar <foo>) by requiring a trailing space.
(while (re-search-forward
"^(\\(def[^ ]+\\) ['(]*\\([^' ()\"\n]+\\)[\n \t]" nil t)
"^(\\(def[^ \t\n]+\\)[ \t\n]+['(]*\\([^' ()\"\n]+\\)[\n \t]" nil t)
(unless (member (match-string 1) autoload-ignored-definitions)
(let ((name (match-string-no-properties 2)))
(when (save-excursion
@ -459,7 +479,7 @@ don't include."
(push name prefs)))))
(loaddefs-generate--make-prefixes prefs load-name)))
(defun loaddefs-generate--rubric (file &optional type feature)
(defun loaddefs-generate--rubric (file &optional type feature compile)
"Return a string giving the appropriate autoload rubric for FILE.
TYPE (default \"autoloads\") is a string stating the type of
information contained in FILE. TYPE \"package\" acts like the default,
@ -467,7 +487,9 @@ but adds an extra line to the output to modify `load-path'.
If FEATURE is non-nil, FILE will provide a feature. FEATURE may
be a string naming the feature, otherwise it will be based on
FILE's name."
FILE's name.
If COMPILE, don't include a \"don't compile\" cookie."
(let ((lp (and (equal type "package") (setq type "autoloads"))))
(with-temp-buffer
(generate-lisp-file-heading
@ -481,30 +503,10 @@ FILE's name."
(insert " \n;;; End of scraped data\n\n")
(generate-lisp-file-trailer
file :provide (and (stringp feature) feature)
:compile compile
:inhibit-provide (not feature))
(buffer-string))))
(defun loaddefs-generate--insert-section-header (outbuf autoloads
load-name file time)
"Insert into buffer OUTBUF the section-header line for FILE.
The header line lists the file name, its \"load name\", its autoloads,
and the time the FILE was last updated (the time is inserted only
if `autoload-timestamps' is non-nil, otherwise a fixed fake time is inserted)."
(insert "\f\n;;;### ")
(prin1 `(autoloads ,autoloads ,load-name ,file ,time)
outbuf)
(terpri outbuf)
;; Break that line at spaces, to avoid very long lines.
;; Make each sub-line into a comment.
(with-current-buffer outbuf
(save-excursion
(forward-line -1)
(while (not (eolp))
(move-to-column 64)
(skip-chars-forward "^ \n")
(or (eolp)
(insert "\n" ";;;;;; "))))))
;;;###autoload
(defun loaddefs-generate (dir output-file &optional excluded-files
extra-data include-package-version
@ -517,15 +519,21 @@ binds `generated-autoload-file' as a file-local variable, write
its autoloads into the specified file instead.
The function does NOT recursively descend into subdirectories of the
directory or directories specified.
directory or directories specified by DIRS.
If EXTRA-DATA, include this string at the start of the generated
file. This will also force generation of OUTPUT-FILE even if
there are no autoloads to put into the file.
Optional argument EXCLUDED-FILES, if non-nil, should be a list of
files, such as preloaded files, whose autoloads should not be written
to OUTPUT-FILE.
If INCLUDE-PACKAGE-VERSION, include package version data.
If EXTRA-DATA is non-nil, it should be a string; include that string
at the beginning of the generated file. This will also force the
generation of OUTPUT-FILE even if there are no autoloads to put into
that file.
If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
If INCLUDE-PACKAGE-VERSION is non-nil, include package version data.
If GENERATE-FULL is non-nil, regenerate all the loaddefs files anew,
instead of just updating them with the new/changed autoloads."
(let* ((files-re (let ((tmp nil))
(dolist (suf (get-load-suffixes))
;; We don't use module-file-suffix below because
@ -585,7 +593,8 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
(with-temp-buffer
(if (and updating (file-exists-p loaddefs-file))
(insert-file-contents loaddefs-file)
(insert (loaddefs-generate--rubric loaddefs-file nil t))
(insert (loaddefs-generate--rubric
loaddefs-file nil t include-package-version))
(search-backward "\f")
(when extra-data
(insert extra-data)
@ -631,18 +640,19 @@ If GENERATE-FULL, don't update, but regenerate all the loaddefs files."
t "GEN")))))))
(defun loaddefs-generate--print-form (def)
"Print DEF in the way make-docfile.c expects it."
"Print DEF in a format that makes sense for version control."
(if (or (not (consp def))
(not (symbolp (car def)))
(memq (car def) '( make-obsolete
define-obsolete-function-alias))
(not (stringp (nth 3 def))))
(prin1 def (current-buffer) t)
;; The salient point here is that we have to have the doc string
;; that starts with a backslash and a newline, and there mustn't
;; be any newlines before that. So -- typically
;; (defvar foo 'value "\
;; Doc string" ...).
;; We want to print, for instance, `defvar' values while escaping
;; control characters (so that we don't end up with lines with
;; trailing tab characters and the like), but we don't want to do
;; this for doc strings, because then the doc strings would be on
;; one single line, which would lead to more VC churn. So --
;; typically (defvar foo 'value "\ Doc string" ...).
(insert "(")
(dotimes (_ 3)
(prin1 (pop def) (current-buffer)

View file

@ -1064,7 +1064,9 @@ untar into a directory named DIR; otherwise, signal an error."
(unless (file-exists-p file)
(require 'autoload)
(let ((coding-system-for-write 'utf-8-emacs-unix))
(write-region (autoload-rubric file "package" nil) nil file nil 'silent)))
(with-suppressed-warnings ((obsolete autoload-rubric))
(write-region (autoload-rubric file "package" nil)
nil file nil 'silent))))
file)
(defvar autoload-timestamps)
@ -2127,7 +2129,10 @@ If PACKAGE is a `package-desc' object, MIN-VERSION is ignored."
package-activated-list)
;; We used the quickstart: make it possible to use package-installed-p
;; even before package is fully initialized.
(memq package package-activated-list))
(or
(memq package package-activated-list)
;; Also check built-in packages.
(package-built-in-p package min-version)))
(t
(or
(let ((pkg-descs (cdr (assq package (package--alist)))))
@ -3597,7 +3602,7 @@ If optional arg BUTTON is non-nil, describe its associated package."
(let ((place (cdr desc))
(out (copy-sequence (car desc))))
(add-text-properties place (1+ place)
'(face (bold font-lock-warning-face))
'(face help-key-binding)
out)
out))
(package--prettify-quick-help-key (cons desc 0))))

View file

@ -455,6 +455,33 @@ TESTFN is used to compare elements, or `equal' if TESTFN is nil."
(setq result (cons elt result))))
(nreverse result)))
(cl-defmethod seq-uniq ((sequence list) &optional testfn)
(let ((result nil))
(if (not testfn)
;; Fast path. If the list is long, use a hash table to speed
;; things up even more.
(let ((l (length sequence)))
(if (> l 100)
(let ((hash (make-hash-table :test #'equal :size l)))
(while sequence
(unless (gethash (car sequence) hash)
(setf (gethash (car sequence) hash) t)
(push (car sequence) result))
(setq sequence (cdr sequence))))
;; Short list.
(while sequence
(unless (member (car sequence) result)
(push (car sequence) result))
(pop sequence))))
;; Slower path.
(while sequence
(unless (seq-find (lambda (elem)
(funcall testfn elem (car sequence)))
result)
(push (car sequence) result))
(pop sequence)))
(nreverse result)))
(cl-defgeneric seq-mapcat (function sequence &optional type)
"Concatenate the result of applying FUNCTION to each element of SEQUENCE.
The result is a sequence of type TYPE, or a list if TYPE is nil."

View file

@ -503,7 +503,7 @@ A FUNC form can have any number of `:no-eval' (or `:no-value'),
(set-file-modes
:no-value "(set-file-modes \"/tmp/foo\" #o644)")
(set-file-times
:no-value (set-file-times "/tmp/foo" (current-time)))
:no-value (set-file-times "/tmp/foo"))
"File Modes"
(set-default-file-modes
:no-value "(set-default-file-modes #o755)")

View file

@ -118,6 +118,7 @@ the resulting string may be longer than the original if LENGTH is
(concat "..." (substring string (min (1- strlen)
(max 0 (- strlen length))))))))
;;;###autoload
(defsubst string-blank-p (string)
"Check whether STRING is either empty or only whitespace.
The following characters count as whitespace here: space, tab, newline and
@ -253,13 +254,9 @@ the string."
(unless (natnump length)
(signal 'wrong-type-argument (list 'natnump length)))
(let ((pad-length (- length (length string))))
(if (< pad-length 0)
string
(concat (and start
(make-string pad-length (or padding ?\s)))
string
(and (not start)
(make-string pad-length (or padding ?\s)))))))
(cond ((<= pad-length 0) string)
(start (concat (make-string pad-length (or padding ?\s)) string))
(t (concat string (make-string pad-length (or padding ?\s)))))))
(defun string-chop-newline (string)
"Remove the final newline (if any) from STRING."

View file

@ -122,7 +122,7 @@ of SECS seconds since the epoch. SECS may be a fraction."
(setq ticks (ash ticks 1))
(setq hz (ash hz 1)))
(let ((more-ticks (+ ticks trunc-s-ticks)))
(time-convert (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz)))))
(time-convert (cons (- more-ticks (% more-ticks trunc-s-ticks)) hz) t))))
(defun timer-relative-time (time secs &optional usecs psecs)
"Advance TIME by SECS seconds.
@ -159,32 +159,42 @@ SECS may be a fraction."
timer)
(defun timer--activate (timer &optional triggered-p reuse-cell idle)
(if (and (timerp timer)
(integerp (timer--high-seconds timer))
(integerp (timer--low-seconds timer))
(integerp (timer--usecs timer))
(integerp (timer--psecs timer))
(timer--function timer))
(let ((timers (if idle timer-idle-list timer-list))
last)
;; Skip all timers to trigger before the new one.
(while (and timers (timer--time-less-p (car timers) timer))
(setq last timers
timers (cdr timers)))
(if reuse-cell
(progn
(setcar reuse-cell timer)
(setcdr reuse-cell timers))
(setq reuse-cell (cons timer timers)))
;; Insert new timer after last which possibly means in front of queue.
(setf (cond (last (cdr last))
(idle timer-idle-list)
(t timer-list))
reuse-cell)
(setf (timer--triggered timer) triggered-p)
(setf (timer--idle-delay timer) idle)
nil)
(error "Invalid or uninitialized timer")))
(let ((timers (if idle timer-idle-list timer-list))
last)
(cond
((not (and (timerp timer)
(integerp (timer--high-seconds timer))
(integerp (timer--low-seconds timer))
(integerp (timer--usecs timer))
(integerp (timer--psecs timer))
(timer--function timer)))
(error "Invalid or uninitialized timer"))
;; FIXME: This is not reliable because `idle-delay' is only set late,
;; by `timer-activate-when-idle' :-(
;;((not (eq (not idle)
;; (not (timer--idle-delay timer))))
;; (error "idle arg %S out of sync with idle-delay field of timer: %S"
;; idle timer))
((memq timer timers)
(error "Timer already activated"))
(t
;; Skip all timers to trigger before the new one.
(while (and timers (timer--time-less-p (car timers) timer))
(setq last timers
timers (cdr timers)))
(if reuse-cell
(progn
(setcar reuse-cell timer)
(setcdr reuse-cell timers))
(setq reuse-cell (cons timer timers)))
;; Insert new timer after last which possibly means in front of queue.
(setf (cond (last (cdr last))
(idle timer-idle-list)
(t timer-list))
reuse-cell)
(setf (timer--triggered timer) triggered-p)
(setf (timer--idle-delay timer) idle)
nil))))
(defun timer-activate (timer &optional triggered-p reuse-cell)
"Insert TIMER into `timer-list'.
@ -216,7 +226,7 @@ the time of the current timer. That's because the activated
timer will fire right away."
(timer--activate timer (not dont-wait) reuse-cell 'idle))
(defalias 'disable-timeout 'cancel-timer)
(defalias 'disable-timeout #'cancel-timer)
(defun cancel-timer (timer)
"Remove TIMER from the list of active timers."
@ -430,7 +440,7 @@ The action is to call FUNCTION with arguments ARGS.
This function returns a timer object which you can use in `cancel-timer'."
(interactive "sRun after delay (seconds): \nNRepeat interval: \naFunction: ")
(apply 'run-at-time secs repeat function args))
(apply #'run-at-time secs repeat function args))
(defun add-timeout (secs function object &optional repeat)
"Add a timer to run SECS seconds from now, to call FUNCTION on OBJECT.
@ -457,7 +467,7 @@ This function returns a timer object which you can use in `cancel-timer'."
(interactive
(list (read-from-minibuffer "Run after idle (seconds): " nil nil t)
(y-or-n-p "Repeat each time Emacs is idle? ")
(intern (completing-read "Function: " obarray 'fboundp t))))
(intern (completing-read "Function: " obarray #'fboundp t))))
(let ((timer (timer-create)))
(timer-set-function timer function args)
(timer-set-idle-time timer secs repeat)

View file

@ -209,7 +209,7 @@ SUPPRESS-LIST is the list of kinds of warnings to suppress."
(text " stop "))
"Suppress warnings."
:version "29.1"
:help-echo "Click to supress this warning type")
:help-echo "Click to suppress this warning type")
(defun warnings-suppress (type)
(pcase (car