(buffer-match-p): Replace &optional with &rest (bug#65797)

* lisp/subr.el (buffer-match-p--past-warnings): New var.
(buffer-match-p): Use it.  Replace `&optional arg` with `&rest args`.
(match-buffers): Replace `&optional arg` with `&rest args`.

* lisp/window.el (display-buffer-alist): Fix out of date docstring.

* doc/lispref/buffers.texi (Buffer List): Document new calling convention.
This commit is contained in:
Stefan Monnier 2023-10-20 20:42:04 -04:00
parent 696411ab8a
commit c94b6397bd
4 changed files with 38 additions and 24 deletions

View file

@ -957,10 +957,10 @@ with a @code{nil} @var{norecord} argument since this may lead to
infinite recursion.
@end defvar
@defun buffer-match-p condition buffer-or-name &optional arg
@defun buffer-match-p condition buffer-or-name &rest args
This function checks if a buffer designated by @code{buffer-or-name}
satisfies the specified @code{condition}. Optional third argument
@var{arg} is passed to the predicate function in @var{condition}. A
satisfies the specified @code{condition}. Optional arguments
@var{args} are passed to the predicate function in @var{condition}. A
valid @var{condition} can be one of the following:
@itemize @bullet{}
@item
@ -969,23 +969,21 @@ satisfies the condition if the regular expression matches the buffer
name.
@item
A predicate function, which should return non-@code{nil} if the buffer
matches. If the function expects one argument, it is called with
@var{buffer-or-name} as the argument; if it expects 2 arguments, the
first argument is @var{buffer-or-name} and the second is @var{arg}
(or @code{nil} if @var{arg} is omitted).
matches. It is called with
@var{buffer-or-name} as the first argument followed by @var{args}.
@item
A cons-cell @code{(@var{oper} . @var{expr})} where @var{oper} is one
of
@table @code
@item (not @var{cond})
Satisfied if @var{cond} doesn't satisfy @code{buffer-match-p} with
the same buffer and @code{arg}.
the same buffer and @code{args}.
@item (or @var{conds}@dots{})
Satisfied if @emph{any} condition in @var{conds} satisfies
@code{buffer-match-p}, with the same buffer and @code{arg}.
@code{buffer-match-p}, with the same buffer and @code{args}.
@item (and @var{conds}@dots{})
Satisfied if @emph{all} the conditions in @var{conds} satisfy
@code{buffer-match-p}, with the same buffer and @code{arg}.
@code{buffer-match-p}, with the same buffer and @code{args}.
@item derived-mode
Satisfied if the buffer's major mode derives from @var{expr}.
@item major-mode
@ -998,14 +996,14 @@ string) or @code{(and)} (empty conjunction).
@end itemize
@end defun
@defun match-buffers condition &optional buffer-list arg
@defun match-buffers condition &optional buffer-list &rest args
This function returns a list of all buffers that satisfy the
@code{condition}. If no buffers match, the function returns
@code{nil}. The argument @var{condition} is as defined in
@code{buffer-match-p} above. By default, all the buffers are
considered, but this can be restricted via the optional argument
@code{buffer-list}, which should be a list of buffers to consider.
Optional third argument @var{arg} will be passed to @var{condition} in
Remaining arguments @var{args} will be passed to @var{condition} in
the same way as @code{buffer-match-p} does.
@end defun

View file

@ -961,6 +961,13 @@ the file listing's performance is still optimized.
* Incompatible Lisp Changes in Emacs 30.1
** `buffer-match-p and `match-buffers` take `&rest args`
They used to take a single `&optional arg` and were documented to use
an unreliable hack to try and support condition predicates that
don't accept this optional arg.
The new semantics makes no such accommodation, but the code still
supports it (with a warning) for backward compatibility.
** 'post-gc-hook' runs after updating 'gcs-done' and 'gcs-elapsed'.
---

View file

@ -7278,13 +7278,15 @@ lines."
(setq start (length string)))))
(nreverse lines))))
(defun buffer-match-p (condition buffer-or-name &optional arg)
(defvar buffer-match-p--past-warnings nil)
(defun buffer-match-p (condition buffer-or-name &rest args)
"Return non-nil if BUFFER-OR-NAME matches CONDITION.
CONDITION is either:
- the symbol t, to always match,
- the symbol nil, which never matches,
- a regular expression, to match a buffer name,
- a predicate function that takes BUFFER-OR-NAME and ARG as
- a predicate function that takes BUFFER-OR-NAME plus ARGS as
arguments, and returns non-nil if the buffer matches,
- a cons-cell, where the car describes how to interpret the cdr.
The car can be one of the following:
@ -7309,9 +7311,18 @@ CONDITION is either:
((pred stringp)
(string-match-p condition (buffer-name buffer)))
((pred functionp)
(if (eq 1 (cdr (func-arity condition)))
(funcall condition buffer-or-name)
(funcall condition buffer-or-name arg)))
(if (cdr args)
;; New in Emacs>29.1. no need for compatibility hack.
(apply condition buffer-or-name args)
(condition-case-unless-debug err
(apply condition buffer-or-name args)
(wrong-number-of-arguments
(unless (member condition
buffer-match-p--past-warnings)
(message "%s" (error-message-string err))
(push condition buffer-match-p--past-warnings))
(apply condition buffer-or-name
(if args nil '(nil)))))))
(`(major-mode . ,mode)
(eq
(buffer-local-value 'major-mode buffer)
@ -7333,17 +7344,17 @@ CONDITION is either:
(throw 'match t)))))))
(funcall match (list condition))))
(defun match-buffers (condition &optional buffers arg)
(defun match-buffers (condition &optional buffers &rest args)
"Return a list of buffers that match CONDITION, or nil if none match.
See `buffer-match-p' for various supported CONDITIONs.
By default all buffers are checked, but the optional
argument BUFFERS can restrict that: its value should be
an explicit list of buffers to check.
Optional argument ARG is passed to `buffer-match-p', for
Optional arguments ARGS are passed to `buffer-match-p', for
predicate conditions in CONDITION."
(let (bufs)
(dolist (buf (or buffers (buffer-list)))
(when (buffer-match-p condition (get-buffer buf) arg)
(when (apply #'buffer-match-p condition (get-buffer buf) args)
(push buf bufs)))
bufs))

View file

@ -7535,10 +7535,8 @@ where:
arguments: a buffer to display and an alist of the same form as
ALIST. See `display-buffer' for details.
`display-buffer' scans this alist until it either finds a
matching regular expression or the function specified by a
condition returns non-nil. In any of these cases, it adds the
associated action to the list of actions it will try."
`display-buffer' scans this alist until the CONDITION is satisfied
and adds the associated ACTION to the list of actions it will try."
:type `(alist :key-type
(choice :tag "Condition"
regexp