New keymap tab-line-mode-map and new tab order on tab-line (bug#69993)

* lisp/tab-line.el (tab-line-new-button-functions): New variable.
(tab-line-tabs-function): Change the default value from
'tab-line-tabs-window-buffers' to the new option
'tab-line-tabs-fixed-window-buffers'.
(tab-line-tabs-buffer-group-sort-function): Change the default
value from nil to 'tab-line-tabs-buffer-group-sort-by-name'.
(tab-line-tabs-buffer-group-sort-by-name): New function.
(tab-line-tabs-fixed-window-buffers): New function.
(tab-line-format-template): Use 'tab-line-new-button-functions'.
(tab-line-mode-map, tab-line-switch-repeat-map): New keymaps.
This commit is contained in:
Juri Linkov 2024-04-17 20:55:45 +03:00
parent 91333dacfa
commit 230eecf12a
2 changed files with 68 additions and 6 deletions

View file

@ -370,11 +370,33 @@ By default it contains a keybinding 'C-TAB' to switch tabs,
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

View file

@ -210,6 +210,11 @@ If the value is a function, call it with no arguments."
'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.
@ -333,18 +338,21 @@ If truncated, append ellipsis per `tab-line-tab-name-ellipsis'."
'help-echo tab-name))))
(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"
@ -400,9 +408,13 @@ as a group name."
: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.")
@ -515,6 +527,21 @@ variable `tab-line-tabs-function'."
(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))
(defcustom tab-line-tab-name-format-function #'tab-line-tab-name-format-default
"Function to format a tab name.
@ -599,7 +626,7 @@ This is used by `tab-line-format'."
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)))))
@ -940,7 +967,7 @@ buffers, which effectively hides the buffer's tab from the tab line.
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"))
@ -1033,6 +1060,19 @@ However, return the correct mouse position list if EVENT is a
(event-start event)))
(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."