Add Numbers to Emacs tab-bar-mode Tab Titles for Quick Access
For about two months now, I’ve been using tab-bar-mode
in Emacs to have multiple “workspaces” open.
I was fine with buffer switching, too. But tab-bar-mode
not only allows you to switch between buffers, but also window configurations – that means one tab will have 1 window with 1 buffer visiting a file, while another might have a gazillion split panes. So the main upside for me is to arrange stuff into panes aka windows, and then open a new tab to do something in a single-pane view.
One thing I added recently is enumeration of tabs so I can jump to them by number. The default tab-bar-keymap
is activated via C-x t, and I didn’t need C-x t 1–C-x t 9. I remapped these keys to go to tabs 1–9. Note that I leave C-x t 0 to close the current tab and switch to another, similar to how C-x 0 closes a window pane.
But with more than 3 tabs open at the same time, I had to count tabs to make this work. That sucks.
So I tried to insert the tab index into its title. But appending (1)
–(9)
takes up 3 characters, which is quite a lot even with a variable pitch (aka non-monospaced font).
I eventually settled for prepending a circled unicode character. For reuse, I extracted an association list of integer values to circled unicode number characters:
(defvar ct/circle-numbers-alist
'((0 . "⓪")
(1 . "①")
(2 . "②")
(3 . "③")
(4 . "④")
(5 . "⑤")
(6 . "⑥")
(7 . "⑦")
(8 . "⑧")
(9 . "⑨"))
"Alist of integers to strings of circled unicode numbers.")
You can use this mapping via e.g. (alist-get 4 ct/circle-numers-alist)
and would get "④"
.
Now here’s how I modified the tab bar format function to display that (and a couple other things) through basic string concatenation:
(defun ct/tab-bar-tab-name-format-default (tab i)
(let ((current-p (eq (car tab) 'current-tab))
(tab-num (if (and tab-bar-tab-hints (< i 10))
(alist-get i ct/circle-numbers-alist) "")))
(propertize
(concat tab-num
" "
(alist-get 'name tab)
(or (and tab-bar-close-button-show
(not (eq tab-bar-close-button-show
(if current-p 'non-selected 'selected)))
tab-bar-close-button)
"")
" ")
'face (funcall tab-bar-tab-face-function tab))))
(setq tab-bar-tab-name-format-function #'ct/tab-bar-tab-name-format-default)
Update 2022-09-19: sorpet pointed out in the comments that you need to enable tab hints:
(setq tab-bar-tab-hints t)
Totally forgot about that!
Update 2022-12-29: I’ve updated my code to use SF Symbols to render the numbers a bit tighter.