* 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.
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
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
@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
\f
* 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'.
---
(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:
((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)
(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))
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