summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/bytecomp.el2
-rw-r--r--lisp/emacs-lisp/cl-lib.el10
-rw-r--r--lisp/emacs-lisp/cl-macs.el38
-rw-r--r--lisp/emacs-lisp/easy-mmode.el38
-rw-r--r--lisp/emacs-lisp/eldoc.el19
-rw-r--r--lisp/emacs-lisp/find-func.el17
-rw-r--r--lisp/emacs-lisp/package.el25
-rw-r--r--lisp/emacs-lisp/rmc.el2
-rw-r--r--lisp/emacs-lisp/subr-x.el4
9 files changed, 103 insertions, 52 deletions
diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el
index 40b4e2f4671..2fab11c79df 100644
--- a/lisp/emacs-lisp/bytecomp.el
+++ b/lisp/emacs-lisp/bytecomp.el
@@ -4071,7 +4071,7 @@ that suppresses all warnings during execution of BODY."
,condition '(fboundp functionp)
byte-compile-unresolved-functions))
(bound-list (byte-compile-find-bound-condition
- ,condition '(boundp default-boundp)))
+ ,condition '(boundp default-boundp local-variable-p)))
;; Maybe add to the bound list.
(byte-compile-bound-variables
(append bound-list byte-compile-bound-variables)))
diff --git a/lisp/emacs-lisp/cl-lib.el b/lisp/emacs-lisp/cl-lib.el
index 7b22fa8483a..ff096918173 100644
--- a/lisp/emacs-lisp/cl-lib.el
+++ b/lisp/emacs-lisp/cl-lib.el
@@ -110,6 +110,7 @@ a future Emacs interpreter will be able to use it.")
;; These macros are defined here so that they
;; can safely be used in init files.
+;;;###autoload
(defmacro cl-incf (place &optional x)
"Increment PLACE by X (1 by default).
PLACE may be a symbol, or any generalized variable allowed by `setf'.
@@ -129,9 +130,12 @@ The return value is the decremented value of PLACE."
(list 'cl-callf '- place (or x 1))))
(defmacro cl-pushnew (x place &rest keys)
- "(cl-pushnew X PLACE): insert X at the head of the list if not already there.
-Like (push X PLACE), except that the list is unmodified if X is `eql' to
-an element already on the list.
+ "Add X to the list stored in PLACE unless X is already in the list.
+PLACE is a generalized variable that stores a list.
+
+Like (push X PLACE), except that PLACE is unmodified if X is `eql'
+to an element already in the list stored in PLACE.
+
\nKeywords supported: :test :test-not :key
\n(fn X PLACE [KEYWORD VALUE]...)"
(declare (debug
diff --git a/lisp/emacs-lisp/cl-macs.el b/lisp/emacs-lisp/cl-macs.el
index 05a4192dd9b..a02fae391bc 100644
--- a/lisp/emacs-lisp/cl-macs.el
+++ b/lisp/emacs-lisp/cl-macs.el
@@ -2906,7 +2906,16 @@ Supported keywords for slots are:
(error "Duplicate slots named %s in %s" slot name))
(let ((accessor (intern (format "%s%s" conc-name slot)))
(default-value (pop desc))
- (doc (plist-get desc :documentation)))
+ (doc (plist-get desc :documentation))
+ (access-body
+ `(progn
+ ,@(and pred-check
+ (list `(or ,pred-check
+ (signal 'wrong-type-argument
+ (list ',name cl-x)))))
+ ,(if (memq type '(nil vector)) `(aref cl-x ,pos)
+ (if (= pos 0) '(car cl-x)
+ `(nth ,pos cl-x))))))
(push slot slots)
(push default-value defaults)
;; The arg "cl-x" is referenced by name in eg pred-form
@@ -2916,13 +2925,7 @@ Supported keywords for slots are:
slot name
(if doc (concat "\n" doc) ""))
(declare (side-effect-free t))
- ,@(and pred-check
- (list `(or ,pred-check
- (signal 'wrong-type-argument
- (list ',name cl-x)))))
- ,(if (memq type '(nil vector)) `(aref cl-x ,pos)
- (if (= pos 0) '(car cl-x)
- `(nth ,pos cl-x))))
+ ,access-body)
forms)
(when (cl-oddp (length desc))
(push
@@ -2942,11 +2945,18 @@ Supported keywords for slots are:
forms)
(push kw desc)
(setcar defaults nil))))
- (if (plist-get desc ':read-only)
- (push `(gv-define-expander ,accessor
- (lambda (_cl-do _cl-x)
- (error "%s is a read-only slot" ',accessor)))
- forms)
+ (cond
+ ((eq defsym 'defun)
+ (unless (plist-get desc ':read-only)
+ (push `(defun ,(gv-setter accessor) (val cl-x)
+ (setf ,access-body val))
+ forms)))
+ ((plist-get desc ':read-only)
+ (push `(gv-define-expander ,accessor
+ (lambda (_cl-do _cl-x)
+ (error "%s is a read-only slot" ',accessor)))
+ forms))
+ (t
;; For normal slots, we don't need to define a setf-expander,
;; since gv-get can use the compiler macro to get the
;; same result.
@@ -2964,7 +2974,7 @@ Supported keywords for slots are:
;; ,(and pred-check `',pred-check)
;; ,pos)))
;; forms)
- )
+ ))
(if print-auto
(nconc print-func
(list `(princ ,(format " %s" slot) cl-s)
diff --git a/lisp/emacs-lisp/easy-mmode.el b/lisp/emacs-lisp/easy-mmode.el
index be531aab849..bbc3a27504c 100644
--- a/lisp/emacs-lisp/easy-mmode.el
+++ b/lisp/emacs-lisp/easy-mmode.el
@@ -363,18 +363,21 @@ No problems result if this variable is not bound.
;;;###autoload
(defalias 'define-global-minor-mode 'define-globalized-minor-mode)
;;;###autoload
-(defmacro define-globalized-minor-mode (global-mode mode turn-on &rest keys)
+(defmacro define-globalized-minor-mode (global-mode mode turn-on &rest body)
"Make a global mode GLOBAL-MODE corresponding to buffer-local minor MODE.
TURN-ON is a function that will be called with no args in every buffer
and that should try to turn MODE on if applicable for that buffer.
-KEYS is a list of CL-style keyword arguments. As the minor mode
- defined by this function is always global, any :global keyword is
- ignored. Other keywords have the same meaning as in `define-minor-mode',
- which see. In particular, :group specifies the custom group.
- The most useful keywords are those that are passed on to the
- `defcustom'. It normally makes no sense to pass the :lighter
- or :keymap keywords to `define-globalized-minor-mode', since these
- are usually passed to the buffer-local version of the minor mode.
+Each of KEY VALUE is a pair of CL-style keyword arguments. As
+ the minor mode defined by this function is always global, any
+ :global keyword is ignored. Other keywords have the same
+ meaning as in `define-minor-mode', which see. In particular,
+ :group specifies the custom group. The most useful keywords
+ are those that are passed on to the `defcustom'. It normally
+ makes no sense to pass the :lighter or :keymap keywords to
+ `define-globalized-minor-mode', since these are usually passed
+ to the buffer-local version of the minor mode.
+BODY contains code to execute each time the mode is enabled or disabled.
+ It is executed after toggling the mode, and before running GLOBAL-MODE-hook.
If MODE's set-up depends on the major mode in effect when it was
enabled, then disabling and reenabling MODE should make MODE work
@@ -384,7 +387,9 @@ call another major mode in their body.
When a major mode is initialized, MODE is actually turned on just
after running the major mode's hook. However, MODE is not turned
-on if the hook has explicitly disabled it."
+on if the hook has explicitly disabled it.
+
+\(fn GLOBAL-MODE MODE TURN-ON [KEY VALUE]... BODY...)"
(declare (doc-string 2))
(let* ((global-mode-name (symbol-name global-mode))
(mode-name (symbol-name mode))
@@ -404,12 +409,12 @@ on if the hook has explicitly disabled it."
keyw)
;; Check keys.
- (while (keywordp (setq keyw (car keys)))
- (setq keys (cdr keys))
+ (while (keywordp (setq keyw (car body)))
+ (pop body)
(pcase keyw
- (:group (setq group (nconc group (list :group (pop keys)))))
- (:global (setq keys (cdr keys)))
- (_ (push keyw extra-keywords) (push (pop keys) extra-keywords))))
+ (:group (setq group (nconc group (list :group (pop body)))))
+ (:global (pop body))
+ (_ (push keyw extra-keywords) (push (pop body) extra-keywords))))
`(progn
(progn
@@ -446,7 +451,8 @@ See `%s' for more information on %s."
;; Go through existing buffers.
(dolist (buf (buffer-list))
(with-current-buffer buf
- (if ,global-mode (funcall #',turn-on) (when ,mode (,mode -1))))))
+ (if ,global-mode (funcall #',turn-on) (when ,mode (,mode -1)))))
+ ,@body)
;; Autoloading define-globalized-minor-mode autoloads everything
;; up-to-here.
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 16b58632099..2892faae21d 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -207,7 +207,24 @@ expression point is on."
(define-globalized-minor-mode global-eldoc-mode eldoc-mode turn-on-eldoc-mode
:group 'eldoc
:initialize 'custom-initialize-delay
- :init-value t)
+ :init-value t
+ ;; For `read--expression', the usual global mode mechanism of
+ ;; `change-major-mode-hook' runs in the minibuffer before
+ ;; `eldoc-documentation-function' is set, so `turn-on-eldoc-mode'
+ ;; does nothing. Configure and enable eldoc from
+ ;; `eval-expression-minibuffer-setup-hook' instead.
+ (if global-eldoc-mode
+ (add-hook 'eval-expression-minibuffer-setup-hook
+ #'eldoc--eval-expression-setup)
+ (remove-hook 'eval-expression-minibuffer-setup-hook
+ #'eldoc--eval-expression-setup)))
+
+(defun eldoc--eval-expression-setup ()
+ ;; Setup `eldoc', similar to `emacs-lisp-mode'. FIXME: Call
+ ;; `emacs-lisp-mode' itself?
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'elisp-eldoc-documentation-function)
+ (eldoc-mode +1))
;;;###autoload
(defun turn-on-eldoc-mode ()
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el
index 9fc7e4a797d..142c99edd43 100644
--- a/lisp/emacs-lisp/find-func.el
+++ b/lisp/emacs-lisp/find-func.el
@@ -285,10 +285,19 @@ Interactively, prompt for LIBRARY using the one at or near point."
A library name is the filename of an Emacs Lisp library located
in a directory under `load-path' (or `find-function-source-path',
if non-nil)."
- (let* ((dirs (or find-function-source-path load-path))
- (suffixes (find-library-suffixes))
- (table (apply-partially 'locate-file-completion-table
- dirs suffixes))
+ (let* ((suffix-regexp (mapconcat
+ (lambda (suffix)
+ (concat (regexp-quote suffix) "\\'"))
+ (find-library-suffixes)
+ "\\|"))
+ (table (cl-loop for dir in (or find-function-source-path load-path)
+ when (file-readable-p dir)
+ append (mapcar
+ (lambda (file)
+ (replace-regexp-in-string suffix-regexp
+ "" file))
+ (directory-files dir nil
+ suffix-regexp))))
(def (if (eq (function-called-at-point) 'require)
;; `function-called-at-point' may return 'require
;; with `point' anywhere on this line. So wrap the
diff --git a/lisp/emacs-lisp/package.el b/lisp/emacs-lisp/package.el
index a72522ad8f8..ef0c5171de6 100644
--- a/lisp/emacs-lisp/package.el
+++ b/lisp/emacs-lisp/package.el
@@ -1028,6 +1028,7 @@ is wrapped around any parts requiring it."
deps))))
(declare-function lm-header "lisp-mnt" (header))
+(declare-function lm-header-multiline "lisp-mnt" (header))
(declare-function lm-homepage "lisp-mnt" (&optional file))
(declare-function lm-keywords-list "lisp-mnt" (&optional file))
(declare-function lm-maintainer "lisp-mnt" (&optional file))
@@ -1054,8 +1055,7 @@ boundaries."
(narrow-to-region start (point))
(require 'lisp-mnt)
;; Use some headers we've invented to drive the process.
- (let* ((requires-str (lm-header "package-requires"))
- ;; Prefer Package-Version; if defined, the package author
+ (let* (;; Prefer Package-Version; if defined, the package author
;; probably wants us to use it. Otherwise try Version.
(pkg-version
(or (package-strip-rcs-id (lm-header "package-version"))
@@ -1067,9 +1067,9 @@ boundaries."
"Package lacks a \"Version\" or \"Package-Version\" header"))
(package-desc-from-define
file-name pkg-version desc
- (if requires-str
- (package--prepare-dependencies
- (package-read-from-string requires-str)))
+ (and-let* ((require-lines (lm-header-multiline "package-requires")))
+ (package--prepare-dependencies
+ (package-read-from-string (mapconcat #'identity require-lines " "))))
:kind 'single
:url homepage
:keywords keywords
@@ -2894,7 +2894,7 @@ KEYWORDS should be nil or a list of keywords."
(mapcar #'package-menu--print-info-simple info-list))))
(defun package-all-keywords ()
- "Collect all package keywords"
+ "Collect all package keywords."
(let ((key-list))
(package--mapc (lambda (desc)
(setq key-list (append (package-desc--keywords desc)
@@ -2951,7 +2951,7 @@ When none are given, the package matches."
(defun package-menu--generate (remember-pos packages &optional keywords)
"Populate the Package Menu.
- If REMEMBER-POS is non-nil, keep point on the same entry.
+If REMEMBER-POS is non-nil, keep point on the same entry.
PACKAGES should be t, which means to display all known packages,
or a list of package names (symbols) to display.
@@ -3086,12 +3086,15 @@ Return (PKG-DESC [NAME VERSION STATUS DOC])."
"`package-archive-contents' before the latest refresh.")
(defun package-menu-refresh ()
- "Download the Emacs Lisp package archive.
-This fetches the contents of each archive specified in
-`package-archives', and then refreshes the package menu."
+ "In Package Menu, download the Emacs Lisp package archive.
+Fetch the contents of each archive specified in
+`package-archives', and then refresh the package menu. Signal a
+user-error if there is already a refresh running asynchronously."
(interactive)
(unless (derived-mode-p 'package-menu-mode)
(user-error "The current buffer is not a Package Menu"))
+ (when (and package-menu-async package--downloads-in-progress)
+ (user-error "Package refresh is already in progress, please wait..."))
(setq package-menu--old-archive-contents package-archive-contents)
(setq package-menu--new-package-list nil)
(package-refresh-contents package-menu-async))
@@ -3206,7 +3209,7 @@ The full list of keys can be viewed with \\[describe-mode]."
"Return the priority of ARCHIVE.
The archive priorities are specified in
-`package-archive-priorities'. If not given there, the priority
+`package-archive-priorities'. If not given there, the priority
defaults to 0."
(or (cdr (assoc archive package-archive-priorities))
0))
diff --git a/lisp/emacs-lisp/rmc.el b/lisp/emacs-lisp/rmc.el
index 47f3b8dc9cf..13cd1c0f42a 100644
--- a/lisp/emacs-lisp/rmc.el
+++ b/lisp/emacs-lisp/rmc.el
@@ -106,7 +106,7 @@ Usage example:
(setq tchar
(if (and (display-popup-menus-p)
last-input-event ; not during startup
- (listp last-nonmenu-event)
+ (consp last-nonmenu-event)
use-dialog-box)
(x-popup-dialog
t
diff --git a/lisp/emacs-lisp/subr-x.el b/lisp/emacs-lisp/subr-x.el
index f76409c4de8..bb2bf3dd5fa 100644
--- a/lisp/emacs-lisp/subr-x.el
+++ b/lisp/emacs-lisp/subr-x.el
@@ -236,7 +236,9 @@ TRIM-LEFT and TRIM-RIGHT default to \"[ \\t\\n\\r]+\"."
(string-trim-left (string-trim-right string trim-right) trim-left))
(defsubst string-blank-p (string)
- "Check whether STRING is either empty or only whitespace."
+ "Check whether STRING is either empty or only whitespace.
+The following characters count as whitespace here: space, tab, newline and
+carriage return."
(string-match-p "\\`[ \t\n\r]*\\'" string))
(defsubst string-remove-prefix (prefix string)