If your mouse or trackpad supports it, you can now scroll tabs when
the mouse pointer is in the tab line by scrolling left or right.
+---
+*** New tab-line faces and options
+The face 'tab-line-tab-special' is used for tabs whose buffers are
+special, i.e. not file-backed. The face
+'tab-line-tab-inactive-alternate' is used to display inactive tabs
+with an alternating background color, making them easier to
+distinguish between, especially if the face 'tab-line-tab' is
+configured to not display with a box; this alternate face is only
+applied when the option 'tab-line-tab-face-functions' is
+so-configured. That option may also be used to customize tab-line
+faces in other ways.
+
** New bindings in occur-mode, 'next-error-no-select' bound to 'n' and
'previous-error-no-select' bound to 'p'.
;;; Code:
+(require 'cl-lib)
(require 'seq) ; tab-line.el is not pre-loaded so it's safe to use it here
\f
:group 'convenience
:version "27.1")
+(defcustom tab-line-tab-face-functions '(tab-line-tab-face-special)
+ "Functions called to modify tab faces.
+Each function is called with five arguments: the tab, a list of
+all tabs, the face returned by the previously called modifier,
+whether the tab is a buffer, and whether the tab is selected."
+ :type '(repeat
+ (choice (function-item tab-line-tab-face-special)
+ (function-item tab-line-tab-face-inactive-alternating)
+ (function :tag "Custom function")))
+ :group 'tab-line
+ :version "28.1")
+
(defgroup tab-line-faces '((tab-line custom-face)) ; tab-line is defined in faces.el
"Faces used in the tab line."
:group 'tab-line
:version "27.1"
:group 'tab-line-faces)
+(defface tab-line-tab-inactive-alternate
+ `((t (:inherit tab-line-tab-inactive :background "grey65")))
+ "Alternate face for inactive tab-line tabs.
+Applied to alternating tabs when option
+`tab-line-tab-face-functions' includes function
+`tab-line-tab-face-inactive-alternating'."
+ :version "28.1"
+ :group 'tab-line-faces)
+
+(defface tab-line-tab-special
+ '((default (:weight bold))
+ (((supports :slant italic))
+ (:slant italic :weight normal)))
+ "Face for special (i.e. non-file-backed) tabs.
+Applied when option `tab-line-tab-face-functions' includes
+function `tab-line-tab-face-special'."
+ :version "28.1"
+ :group 'tab-line-faces)
+
(defface tab-line-tab-current
'((default
:inherit tab-line-tab)
(cdr (assq 'selected tab))))
(name (if buffer-p
(funcall tab-line-tab-name-function tab tabs)
- (cdr (assq 'name tab)))))
+ (cdr (assq 'name tab))))
+ (face (if selected-p
+ (if (eq (selected-window) (old-selected-window))
+ 'tab-line-tab-current
+ 'tab-line-tab)
+ 'tab-line-tab-inactive)))
+ (dolist (fn tab-line-tab-face-functions)
+ (setf face (funcall fn tab tabs face buffer-p selected-p)))
(concat
separator
(apply 'propertize
`(
tab ,tab
,@(if selected-p '(selected t))
- face ,(if selected-p
- (if (eq (selected-window) (old-selected-window))
- 'tab-line-tab-current
- 'tab-line-tab)
- 'tab-line-tab-inactive)
+ face ,face
mouse-face tab-line-highlight)))))
tabs))
(hscroll-data (tab-line-auto-hscroll strings hscroll)))
tab-line-new-button)
(list tab-line-new-button)))))
+(defun tab-line-tab-face-inactive-alternating (tab tabs face _buffer-p selected-p)
+ "Return FACE for TAB in TABS with alternation.
+When TAB is an inactive buffer and is even-numbered, make FACE
+inherit from `tab-line-tab-inactive-alternate'. For use in
+`tab-line-tab-face-functions'."
+ (when (and (not selected-p) (cl-evenp (cl-position tab tabs)))
+ (setf face `(:inherit (tab-line-tab-inactive-alternate ,face))))
+ face)
+
+(defun tab-line-tab-face-special (tab _tabs face buffer-p _selected-p)
+ "Return FACE for TAB according to whether it's special.
+When TAB is a non-file-backed buffer, make FACE inherit from
+`tab-line-tab-special'. For use in
+`tab-line-tab-face-functions'."
+ (when (and buffer-p (not (buffer-file-name tab)))
+ (setf face `(:inherit (tab-line-tab-special ,face))))
+ face)
+
(defvar tab-line-auto-hscroll)
(defun tab-line-format ()