Subject: Re: bug#69983: Use category for display-buffer-alist

From: Juri Linkov <[email-masked]>
Date: Thu, 28 Mar 2024 19:46:48 +0200

> Please use "If", not "When" in such cases.  "When" has a meaning of
> time, which is not what you mean here.
>
>> +in its @var{action} argument, then @code{display-buffer-alist} can use it
>> +to match a whole category of buffers with different buffer names,
>> +for example:
>> +
>> +@example
>> +@group
>> +(setopt
>> + display-buffer-alist
>> + (cons '((category . comint) (display-buffer-same-window))
>> +        display-buffer-alist))
>> +
>> +(display-buffer (get-buffer-create "*my-shell*")
>> +		'(nil (category . comint)))
>> +@end group
>
> I failed to understand from the description and the example the
> meaning of 'category' in this case.  Specifically, I think the
> description should tell more about the interpretation of the symbol in
> (category . SYMBOL).  The example gives 'comint' as the category
> symbol and says this matches "a whole category of buffers", but
> doesn't explain enough to understand which buffers will match this
> category and which won't.  IOW, the meaning of 'comint' as "category
> of buffers" is not sufficiently explained.

Now this is improved in the patch below.

>> --- a/lisp/subr.el
>> +++ b/lisp/subr.el
>> @@ -7476,6 +7474,8 @@ buffer-match-p
>>    * `major-mode': the buffer matches if the buffer's major mode
>>      is eq to the cons-cell's cdr.  Prefer using `derived-mode'
>>      instead when both can work.
>> +  * `category': the buffer matches if the caller of `display-buffer'
>> +    provided `(category . symbol)' in its ACTION argument.
>
> Same here.  (And "symbol" should be "SYMBOL", upper-case, I think.

Actually symbol is not a function argument here.

diff --git a/doc/lispref/windows.texi b/doc/lispref/windows.texi
index eef05d94fdb..90cd8d2f2da 100644
--- a/doc/lispref/windows.texi
+++ b/doc/lispref/windows.texi
@@ -2638,6 +2638,29 @@ Choosing Window
 @code{buffer-match-p} could fail to report a match if
 @code{display-buffer} is called before the major mode of the buffer is
 set.
+
+If the caller of @code{display-buffer} passes a category as a symbol
+in its @var{action} argument, then you can use the same category in
+@code{display-buffer-alist} to match buffers with different names,
+for example:
+
+@example
+@group
+(setopt
+ display-buffer-alist
+ (cons '((category . comint) (display-buffer-same-window))
+        display-buffer-alist))
+
+(display-buffer (get-buffer-create "*my-shell*")
+		'(nil (category . comint)))
+@end group
+@end example
+
+Regardless of the displayed buffer's name the caller defines a category
+as a symbol @code{comint}.  Then @code{display-buffer-alist} matches
+this category for all buffers displayed with the same category.
+This avoids the need to construct a complex regular expression
+that matches a buffer name.
 @end defopt
 
 @defopt display-buffer-base-action
diff --git a/lisp/subr.el b/lisp/subr.el
index 90dbfc75d52..da57f917da8 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -7476,6 +7474,9 @@ buffer-match-p
   * `major-mode': the buffer matches if the buffer's major mode
     is eq to the cons-cell's cdr.  Prefer using `derived-mode'
     instead when both can work.
+  * `category': the buffer matches a category as a symbol if
+    the caller of `display-buffer' provides `(category . symbol)'
+    in its action argument.
   * `not': the cadr is interpreted as a negation of a condition.
   * `and': the cdr is a list of recursive conditions, that all have
     to be met.
@@ -7504,6 +7505,8 @@ buffer-match-p
                               (push condition buffer-match-p--past-warnings))
                             (apply condition buffer-or-name
                                    (if args nil '(nil)))))))
+                      (`(category . ,category)
+                       (eq (alist-get 'category (cdar args)) category))
                       (`(major-mode . ,mode)
                        (eq
                         (buffer-local-value 'major-mode buffer)