but only when 'C-TAB' is not bound globally. You can unbind it
if it conflicts with 'C-TAB' in other modes.
+---
+*** New keymap 'tab-line-mode-map'.
+By default it contains keybindings for switching tabs:
+'C-x <left>', 'C-x <right>', 'C-x C-<left>', 'C-x C-<right>'.
+You can unbind them if you want to use these keys for the
+commands 'previous-buffer' and 'next-buffer'.
+
+---
+*** Default list of tabs is changed to support a fixed order.
+This means that the new default tabs function
+'tab-line-tabs-fixed-window-buffers' is like the previous
+'tab-line-tabs-window-buffers' where both of them show
+only buffers that were previously displayed in the window.
+But the difference is that the new function always keeps
+the original order of buffers on the tab line, even after
+switching between these buffers.
+
---
*** New user option 'tab-line-tabs-buffer-group-function'.
It provides two choices to group tab buffers by major mode
and by project name.
+---
+*** Now buffers on group tabs are sorted alphabetically.
+This will keep the fixed order of tabs, even after
+switching between them.
+
+++
** New optional argument for modifying directory-local variables.
The commands 'add-dir-local-variable', 'delete-dir-local-variable' and
'help-echo "Click to add tab")
"Button for creating a new tab.")
+(defvar tab-line-new-button-functions
+ '(tab-line-tabs-window-buffers
+ tab-line-tabs-fixed-window-buffers)
+ "Functions of `tab-line-tabs-function' for which to show a new button.")
+
(defcustom tab-line-close-button-show t
"Defines where to show the close tab button.
If t, show the close tab button on all tabs.
'help-echo tab-name))))
\f
-(defcustom tab-line-tabs-function #'tab-line-tabs-window-buffers
+(defcustom tab-line-tabs-function #'tab-line-tabs-fixed-window-buffers
"Function to get a list of tabs to display in the tab line.
This function should return either a list of buffers whose names will
be displayed, or just a list of strings to display in the tab line.
-By default, use function `tab-line-tabs-window-buffers' that
-returns a list of buffers associated with the selected window.
+By default, use function `tab-line-tabs-fixed-window-buffers' that
+returns a list of buffers associated with the selected window where
+buffers always keep the original order after switching buffers.
When `tab-line-tabs-mode-buffers', return a list of buffers
with the same major mode as the current buffer.
When `tab-line-tabs-buffer-groups', return a list of buffers
grouped by `tab-line-tabs-buffer-group-function'."
:type '(choice (const :tag "Window buffers"
tab-line-tabs-window-buffers)
+ (const :tag "Window buffers with fixed order"
+ tab-line-tabs-fixed-window-buffers)
(const :tag "Same mode buffers"
tab-line-tabs-mode-buffers)
(const :tag "Grouped buffers"
:group 'tab-line
:version "30.1")
-(defvar tab-line-tabs-buffer-group-sort-function nil
+(defvar tab-line-tabs-buffer-group-sort-function
+ #'tab-line-tabs-buffer-group-sort-by-name
"Function to sort buffers in a group.")
+(defun tab-line-tabs-buffer-group-sort-by-name (a b)
+ (string< (buffer-name a) (buffer-name b)))
+
(defvar tab-line-tabs-buffer-groups-sort-function #'string<
"Function to sort group names.")
(list buffer)
next-buffers)))
+(defun tab-line-tabs-fixed-window-buffers ()
+ "Like `tab-line-tabs-window-buffers' but keep stable sorting order.
+This means that switching to a buffer previously shown in the same
+window will keep the same order of tabs that was before switching.
+And newly displayed buffers are added to the end of the tab line."
+ (let* ((old-buffers (window-parameter nil 'tab-line-fixed-window-buffers))
+ (new-buffers (sort (tab-line-tabs-window-buffers)
+ (lambda (a b)
+ (< (or (seq-position old-buffers a)
+ most-positive-fixnum)
+ (or (seq-position old-buffers b)
+ most-positive-fixnum))))))
+ (set-window-parameter nil 'tab-line-fixed-window-buffers new-buffers)
+ new-buffers))
+
\f
(defcustom tab-line-tab-name-format-function #'tab-line-tab-name-format-default
"Function to format a tab name.
tab-line-right-button)))
(if hscroll (nthcdr (truncate hscroll) strings) strings)
(list separator)
- (when (and (eq tab-line-tabs-function #'tab-line-tabs-window-buffers)
+ (when (and (memq tab-line-tabs-function tab-line-new-button-functions)
tab-line-new-button-show
tab-line-new-button)
(list tab-line-new-button)))))
If `kill-buffer', kills the tab's buffer.
When a function, it is called with the tab as its argument.
This option is useful when `tab-line-tabs-function' has the value
-`tab-line-tabs-window-buffers'."
+`tab-line-tabs-window-buffers' or `tab-line-tabs-fixed-window-buffers'."
:type '(choice (const :tag "Bury buffer" bury-buffer)
(const :tag "Kill buffer" kill-buffer)
(function :tag "Function"))
(event-start event)))
\f
+(defvar-keymap tab-line-mode-map
+ :doc "Keymap for keys of `tab-line-mode'."
+ "C-x <left>" #'tab-line-switch-to-prev-tab
+ "C-x C-<left>" #'tab-line-switch-to-prev-tab
+ "C-x <right>" #'tab-line-switch-to-next-tab
+ "C-x C-<right>" #'tab-line-switch-to-next-tab)
+
+(defvar-keymap tab-line-switch-repeat-map
+ :doc "Keymap to repeat tab/buffer cycling. Used in `repeat-mode'."
+ :repeat t
+ "<left>" #'tab-line-switch-to-prev-tab
+ "<right>" #'tab-line-switch-to-next-tab)
+
;;;###autoload
(define-minor-mode tab-line-mode
"Toggle display of tab line in the windows displaying the current buffer."