Ok - so I've come up with a solution. It's not too pretty, and it needs polishing, but it works. Keen to hear any suggestions anyone has.
I am declaring a list that is my list of tabs to display, and tab-line-tabs-function
draws from this.
(global-tab-line-mode)
(setq my/current-tab-list (list (current-buffer)))
(setq tab-line-tabs-function 'tab-line-tabs-mode-buffers)
(defun tab-line-tabs-mode-buffers ()
my/current-tab-list)
The following function adds new buffers to this list. I add this as a hook to find-file and dired-mode to automatically add new buffers as I open them.
(defun my/add-current-buffer-to-tab ()
(interactive)
(setq my/current-tab-list (add-to-list 'my/current-tab-list (current-buffer)))
)
(add-hook 'find-file-hook 'my/add-current-buffer-to-tab)
(add-hook 'dired-mode-hook 'my/add-current-buffer-to-tab)
To remove a buffer from this list when I close it, I call this custom function.
(defun my/close-tab ()
(interactive)
(setq my/current-tab-list (delete (current-buffer) my/current-tab-list))
(kill-buffer)
)
The following functions allow me to manually change the order of the buffers.
(defun my/shift-tab-left ()
(interactive)
(let ((n (seq-position my/current-tab-list (current-buffer))))
(when
(> n 0)
(progn
(setq my/current-tab-list
(append
(seq-take my/current-tab-list (- n 1))
(list (elt my/current-tab-list n))
(list (elt my/current-tab-list (- n 1)))
(seq-drop my/current-tab-list (+ n 1))
))))))
(defun my/shift-tab-right ()
(interactive)
(let ((n (seq-position my/current-tab-list (current-buffer))))
(when
(< n (- (length my/current-tab-list) 1))
(progn
(setq my/current-tab-list
(append
(seq-take my/current-tab-list n)
(list (elt my/current-tab-list (+ n 1)))
(list (elt my/current-tab-list n ))
(seq-drop my/current-tab-list (+ n 2))
)))))))
Sometimes I want a buffer to be loaded, but not appear in the tab list. For that situation I run the following function:
(defun my/drop-tab ()
(interactive)
(setq my/current-tab-list (delete (current-buffer) my/current-tab-list))
(switch-to-buffer (nth 0 my/current-tab-list))
)
And I use tab-line-switch-to-next-tab
and tab-line-switch-to-prev-tab
to move forwards and backwards.
As I say, needs a bit more polishing, but so far seems to be meeting my needs very nicely and seems robust enough. Sometimes after reordering the tabs it takes a moment to refresh.
Keen for any feedback. Not a programmer, just bodged this together, so will be interested to hear any constructive feedback/elisp rules I have broken.
tab-line-tabs-function
you may be out of luck. See this thread from help-gnu-emacs@.tab-line-tabs-function
is what I have concluded I need to do. I was just planning to copytab-line-tabs-window-buffers
and then have it sort the tabs at the end of this process, by name for instance. Do you know what code would be needed to sort a list of buffers by name? As per that thread, I'll make a new feature request if I can't get there myself.(sort (mapcar #'buffer-name (buffer-list)) #'string<)
will get and sort all buffers, including hidden ones. You'll probably just want the list associated w/ a single frame. Seebuffer-list
'tab-line-tabs-window-buffers
I get persistent tab order! But,tab-line-switch-to-next-tab
andtab-line-switch-to-previous-tab
behave very unexpectedly - they do not respect this new order. Looking atbs
library to generate a newtab-line-tabs-function
and my own function for next/previous tab.