Subject: bug#79159: [PATCH] Do not display in the tab line tabs that are excluded.

From: Elijah Gabe Pérez <[email-masked]>
Date: Mon, 11 Aug 2025 22:29:36 -0600

Juri Linkov <[email-masked]> writes:

>> +(defvar tab-line-tabs-window-buffers-function
>> +  #'tab-line-tabs-window-buffers-default
>> +  "Function for get a list of window buffers.
>> +Used only for `tab-line-tabs-fixed-window-buffers'.")
>
> I wonder why do you need another indirection.  It should be
> sufficient to use tab-line-tabs-window-buffers-filter-function
> in the current implementation of tab-line-tabs-window-buffers,
> especially with the value 'identity' to keep current behavior.

That was to add a simple way to customize the listed buffers in
'tab-line-tabs-fixed-window-buffers', not to be another filter.  I've
reverted it anyways:

>From 80dce7accf3ae369fbc35daf4ad1ceda301ef6d2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Fri, 1 Aug 2025 20:14:59 -0600
Subject: [PATCH] tab-line: Allow to hide excluded buffers in the tab line. 
 (Bug#79159)

* etc/NEWS: Announce changes.
* lisp/tab-line.el (tab-line-tabs-window-buffers-filter-function):
New user option.
(tab-line-tabs-non-excluded): New function.
(tab-line-tabs-window-buffers): Update.
---
 etc/NEWS         |  5 +++++
 lisp/tab-line.el | 31 ++++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 3 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index e12a9dcb127..329eb1203a6 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -436,6 +436,11 @@ a buffer.  The value must be a condition which is passed to
 With this user option, if non-nil (the default), the tab close button
 will change its appearance if the tab buffer has been modified.
 
+---
+*** New user option 'tab-line-tabs-window-buffers-filter-function'.
+This user option controls which buffers should appear in the tab line.
+By default, this is set to not filter the buffers.
+
 ** Project
 
 ---
diff --git a/lisp/tab-line.el b/lisp/tab-line.el
index 51675dbbb29..4b6f71f7a1f 100644
--- a/lisp/tab-line.el
+++ b/lisp/tab-line.el
@@ -565,6 +565,29 @@ tab-line-tabs-buffer-groups
                          sorted-buffers)))
       (cons group-tab tabs))))
 
+(defcustom tab-line-tabs-window-buffers-filter-function
+  #'identity
+  "Filter which buffers should be displayed in the tab line."
+  :type '(choice function
+                 (const :tag "No filter the buffers" identity)
+                 (const :tag "Show non-excluded buffers only" tab-line-tabs-non-excluded))
+  :group 'tab-line)
+
+(defvar tab-line-exclude-buffers)
+(defvar tab-line-exclude-modes)
+
+(defun tab-line-tabs-non-excluded (buffers)
+  "Filter BUFFERS and return non-excluded buffers list.
+Intended to be used in `tab-line-tabs-window-buffers-filter-function'."
+  (seq-remove
+   (lambda (b)
+     (or (memq (buffer-local-value 'major-mode b)
+               tab-line-exclude-modes)
+         (buffer-match-p tab-line-exclude-buffers b)
+         (get (buffer-local-value 'major-mode b) 'tab-line-exclude)
+         (buffer-local-value 'tab-line-exclude b)))
+   buffers))
+
 (defun tab-line-tabs-window-buffers ()
   "Return a list of tabs that should be displayed in the tab line.
 By default returns a list of window buffers, i.e. buffers previously
@@ -581,9 +604,11 @@ tab-line-tabs-window-buffers
          (prev-buffers (seq-filter #'buffer-live-p prev-buffers))
          ;; Remove next-buffers from prev-buffers
          (prev-buffers (seq-difference prev-buffers next-buffers)))
-    (append (reverse prev-buffers)
-            (list buffer)
-            next-buffers)))
+    (funcall
+     tab-line-tabs-window-buffers-filter-function
+     (append (reverse prev-buffers)
+             (list buffer)
+             next-buffers))))
 
 (defun tab-line-tabs-fixed-window-buffers ()
   "Like `tab-line-tabs-window-buffers' but keep stable sorting order.
-- 
2.50.1

>>> > +(defvar tab-line-tabs-window-buffers-filter-function
>>> > +  #'tab-line-tabs-window-buffers-filter-default
>>> > +  "Filter which buffers should be displayed in the tab line.")
>>> 
>>> Shouldn't this be defcustom?  Then you can add a const 'identity'
>>> to allow keeping excluded buffers.
>>
>> Didn't you say that keeping them produces buggy behavior?  If so, why
>> would we tempt users to produce bugs?
>
> It's not so simple.  Currently tab-line is disabled on these conditions:
>
>               (string-match-p "\\` " (buffer-name))
>               (memq major-mode tab-line-exclude-modes)
>               (buffer-match-p tab-line-exclude-buffers (buffer-name))
>               (get major-mode 'tab-line-exclude)
>               (buffer-local-value 'tab-line-exclude (current-buffer)))
>
> Buggy behavior is produced only on the first condition:
> when the buffer name begins with a space.
>
> So the default predicate should use exactly the same conditions
> in the filter to hide buffers on the tab-line.
>
> And also defcustom should provide another value to get back
> almost the same behavior as current, with one exception that
> buffers with names that begin with a space should be hidden too,
> i.e. the second value should match only one condition:
>
>               (string-match-p "\\` " (buffer-name))

>From what I have tested, buffers that start with a space are unlikely to
appear on the tab line by default, so i don't think a new value is
necessary.

-- 
- E.G via Gnus and Org.