The Hidden Value of Emacs’ Tab Bar


  • The Flux Harmonic channel is now live!
  • First stream is next Tuesday, December 21, from 1PM to 4PM UTC

The Hidden Value of Emacs’ Tab Bar

Today we’re going to work on customizing Emacs’ tab-bar-mode to see if it can be used as a replacement for other workspace packages like Perspective.el.

Lots of new things have been added for it in Emacs 28, so let’s try it out!

The Plan

  • Customizing tab display to show selection better (font, color, emoji?)
  • Experiment with tab groups
  • Setting the tab-bar-format, a better status panel?
  • Open project.el projects in new tabs
  • Writing a function to show only desired buffers for a given tab
  • Does it work with desktop-save-mode?

Using tab-bar solely as a global mode line:

The final code

;; Inherit the face of `doom-modeline-panel` for better appearance
(set-face-attribute 'tab-bar-tab nil :inherit 'doom-modeline-panel :foreground nil :background nil)

;; Totally customize the format of the tab bar name
(defun my/tab-bar-format (tab i)
      (if (eq (car tab) 'current-tab)
          "🔥 " "")
    (alist-get 'name tab))
   'face (list (append
                  '(:foreground "#FFFFFF")
                  (if (eq (car tab) 'current-tab)
                      '(:box t)

;; Replace the default tab bar function
(setq tab-bar-tab-name-format-function #'my/tab-bar-format)

(defun my/tab-bar-tab-name-function ()
  (let ((project (project-current)))
    (if project
        (project-root project)

(setq tab-bar-tab-name-function #'my/tab-bar-tab-name-function)

;; Only show the tab bar if there are 2 or more tabs
(setq tab-bar-show 1)

(defun my/tab-bar-string () "HELLO")

;; Customize the tab bar format to add the global mode line string
(setq tab-bar-format '(tab-bar-format-tabs tab-bar-separator tab-bar-format-align-right tab-bar-format-global))

(add-to-list 'global-mode-string "HELLO")

;; Make sure mode line text in the tab bar can be read
(set-face-attribute 'tab-bar nil :foreground "#FFFFFF")

(defun my/project-create-tab ()

(setq project-switch-commands #'my/project-create-tab)

(defun my/switch-to-tab-buffer ()
  (if (project-current)
      (call-interactively #'project-switch-to-buffer)
    (call-interactively #'switch-to-buffer)))

(global-set-key (kbd "C-x b") #'my/switch-to-tab-buffer)

;; Turn on tab bar mode after startup
(tab-bar-mode 1)

;; Save the desktop session
(desktop-save-mode 1)
Subscribe to the System Crafters Newsletter!
Stay up to date with the latest System Crafters news and updates! Read the Newsletter page for more information.
Name (optional)
Email Address