-(defun buffers-tab-items (&optional in-deletion frame)
- "This is the tab filter for the top-level buffers \"Buffers\" tab.
-It dynamically creates a list of buffers to use as the contents of the tab.
-Only the most-recently-used few buffers will be listed on the tab, for
-efficiency reasons. You can control how many buffers will be shown by
-setting `buffers-tab-max-size'. You can control the text of the tab
-items by redefining the function `format-buffers-menu-line'."
- (let* ((buffers (delete-if buffers-tab-omit-function (buffer-list frame)))
- (first-buf (car buffers)))
- ;; if we're in deletion ignore the current buffer
- (when in-deletion
- (setq buffers (delq (current-buffer) buffers))
- (setq first-buf (car buffers)))
- ;; group buffers by mode
- (when buffers-tab-selection-function
- (delete-if-not #'(lambda (buf)
- (funcall buffers-tab-selection-function
- first-buf buf)) buffers))
- (and (integerp buffers-tab-max-size)
- (> buffers-tab-max-size 1)
- (> (length buffers) buffers-tab-max-size)
- ;; shorten list of buffers
- (setcdr (nthcdr buffers-tab-max-size buffers) nil))
- (setq buffers (build-buffers-tab-internal buffers))
- buffers))
+;;; #### SJT would like this function to have a sort function list. I
+;;; don't see how this could work given that sorting is not
+;;; cumulative --andyp.
+(defun buffers-tab-items (&optional in-deletion frame force-selection)
+ "Return a list of tab instantiators based on the current buffers list.
+This function is used as the tab filter for the top-level buffers
+\"Buffers\" tab. It dynamically creates a list of tab instantiators
+to use as the contents of the tab. The contents and order of the list
+is controlled by `buffers-tab-filter-functions' which by default
+groups buffers according to major mode and removes invisible buffers.
+You can control how many buffers will be shown by setting
+`buffers-tab-max-size'. You can control the text of the tab items by
+redefining the function `format-buffers-menu-line'."
+ (save-match-data
+ ;; NB it is too late if we run the omit function as part of the
+ ;; filter functions because we need to know which buffer is the
+ ;; context buffer before they get run.
+ (let* ((buffers (delete-if
+ buffers-tab-omit-function (buffer-list frame)))
+ (first-buf (car buffers)))
+ ;; maybe force the selected window
+ (when (and force-selection
+ (not in-deletion)
+ (not (eq first-buf (window-buffer (selected-window frame)))))
+ (setq buffers (cons (window-buffer (selected-window frame))
+ (delq first-buf buffers))))
+ ;; if we're in deletion ignore the current buffer
+ (when in-deletion
+ (setq buffers (delq (current-buffer) buffers))
+ (setq first-buf (car buffers)))
+ ;; filter buffers
+ (when buffers-tab-filter-functions
+ (setq buffers
+ (delete-if
+ #'null
+ (mapcar #'(lambda (buf)
+ (let ((tmp-buf buf))
+ (mapc #'(lambda (fun)
+ (unless (funcall fun buf first-buf)
+ (setq tmp-buf nil)))
+ buffers-tab-filter-functions)
+ tmp-buf))
+ buffers))))
+ ;; maybe shorten list of buffers
+ (and (integerp buffers-tab-max-size)
+ (> buffers-tab-max-size 1)
+ (> (length buffers) buffers-tab-max-size)
+ (setcdr (nthcdr (1- buffers-tab-max-size) buffers) nil))
+ ;; sort buffers in group (default is most-recently-selected)
+ (when buffers-tab-sort-function
+ (setq buffers (funcall buffers-tab-sort-function buffers)))
+ ;; convert list of buffers to list of structures used by tab widget
+ (setq buffers (build-buffers-tab-internal buffers))
+ buffers)))