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:
commit
1823349e6a
382 changed files with 8154 additions and 6180 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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))))
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
|
|
|
|||
|
|
@ -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."
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue