Note that tabbar mode as implemented in Emacs is a bit different than tabs in web browsers or IDEs. In a web browser, each window may have several tabs, and each window’s tabs stay with that window. Namely, you cannot have Window A’s tab jump to window B, unless you drag it over (Firefox 3 supports this, for example. Safari 3.2 does not.). However, the tabs implemented in emacs with tabbar mode is more like a GUI-based display of buffer listing, displayed on top of the window. In particular, tabs does not stick to a particular emacs’s Frame, and conversely, each Emacs Frame can display a tab that is also shown in another Emacs Frame.

Also, emacs’s tabbar mode’s tab can be hidden, as if showing only the current “page” of a tab set, called a “group”. By default, tabs are grouped by major mode. So, for example, if current buffer is in html-mode, all the tabs shown are other buffers in html-mode. If there are no other html-mode buffers, then you will have only one tab, even if you have lots other buffers. All your dired buffers, C-mode buffers, java-buffers, etc, are in other tab group and is hidden. You have to click on a special tab widget to switch to them, or use keyboard shortcut to switch tab or tab group.

What is considered a tab group can be customized (see section Customization below). You can even set it up to include every buffer in one group.

Tab bar mode is implemented using a special Emacs display area (called the header line) at the top of the Emacs window, not the Emacs frame. (From this it follows that each Emacs window will have its own tab bar, no matter how many times you split the frame.) Some other modes also use this header line, for instance Info, Dired, Slime, ERC, ruler-mode, etc. These modes override tabbar for their own purposes, but you can get the tabs back by typing M-x tabbar-local-mode.

Documentation

The tabbar mode does not have documentation except in the comments of the source file tabbar.el.

Customization

Tab groups

To define your own tab grouping, you need to either set tabbar-buffer-groups to your own function that returns a list of strings, or define your own function with another name and then write (setq tabbar-buffer-groups-function 'your-function-name). Either way works.

Here’s a example of tab group function that define all tabs to be one of two possible groups: “emacs” and “user”.

(defunmy-tabbar-buffer-groups () ;; customize to show all normal files in one group"Returns the name of the tab group names the current buffer belongs to.
There are two groups: Emacs buffers (those whose name starts with '*', plus
dired buffers), and the rest. This works at least with Emacs v24.2 using
tabbar.el v1.7."
(list (cond ((string-equal "*" (substring (buffer-name) 0 1)) "emacs")
((eq major-mode 'dired-mode) "emacs")
(t "user"))))
(setq tabbar-buffer-groups-function 'my-tabbar-buffer-groups)

Another tabbar-buffer-groups example, based on the original tabbar.el’s function of the same name. (Note that this function overrides the original tabbar-buffer-groups function, so there’s no need to call (setq tabbar-buffer-groups-function
'your-function-name).)

The following will group the tabs by the git repository that the file is in. All files that are not in a git repository will be grouped together, and all buffers that do not have a file will be grouped together.

Tab navigation made easy

You can define keystrokes for navigating among the tabs of one tab group. Here we use the meta-right-arrow and meta-left-arrow keystrokes. (These keys normally bind to functions right-word and left-word, which are also bound to ctrl-right-arrow and ctrl-left-arrow, so we’re not losing convenience.)

Disabling locally, depending on the MajorMode

I tried to enable the tabbar for my terminals only with the above configuration, and it turned out that it remains visible even when it does not contain any tab: some empty space remains as headline.

So, I use the following configuration to display the tabbar on certain buffers only (for buffers in term-mode major mode in this case, but it can easily be extended). The tabbar is disabled on the other buffers.

(when (require 'tabbar nil t)
;; Enable tabbars globally:
(tabbar-mode 1)
;; I use this minor-mode mainly as a global mode (see below):
(define-minor-modetabbar-on-term-only-mode"Display tabbar on terminals and buffers in fundamental mode only.":init-value t
:lighter nil
:keymap nil
(if tabbar-on-term-only-mode
;; filter is enabled
(if (eq major-mode 'term-mode); <- this can be easily customizable...
(tabbar-local-mode -1)
(tabbar-local-mode 1))
;; always activate tabbar locally when we disable the minor mode:
(tabbar-local-mode -1)))
(defuntabbar-on-term-only-mode-on ()
"Turn on tabbar if current buffer is a terminal."
(unless (minibufferp) (tabbar-on-term-only-mode 1)))
;; Define a global switch for the mode. Note that this is not set for buffers;; in fundamental mode.;;;; I use it 'cause some major modes do not run the;; `after-change-major-mode-hook'...
(define-globalized-minor-modeglobal-tabbar-on-term-only-mode
tabbar-on-term-only-mode tabbar-on-term-only-mode-on)
;; Eventually, switch on this global filter for tabbars:
(global-tabbar-on-term-only-mode 1))

Certain buffers get put into the #misc group; everything under ~/.emacs.d/ gets put into one group, and everything else gets put into a group with its directory, so that all files in that directory (and associated buffers like compilation) get put together. For multi-directory projects I plan to add special cases like the one for .emacs.d to group buffers under the parent directory.

Speed up by not using images

Tabbar can slow down Emacs considerably, especially simply moving the cursor up or down. This can be rectified by adding this to your .emacs file, which makes Tabbar use characters to represent the three images in the top-left corner:

Questions and Answers

Any way to turn off the tabbar for a specific window/frame, i.e., not globally and not per a specific buffer? – DrewAdams

Here is one way to do it. It is quite hackish and uses deprecated stuff, but it works fine on 24.1.

I use emacs --daemon with both, X and tty frames. My goal is: On ttys, no tab bar (or menu bar) should show in order to preserve screen real-estate. X frames should have all bells and whistles. Since this works on a per-frame base, you can easily adapt it to other scenarios.

;; Allow tab-bar-mode to be frame-local. This is deprecated and exploits;; the fact that `default-header-line-format' is an alias of the global;; value of `header-line-format'. Tested with Emacs 24.1.
(make-variable-frame-local 'default-header-line-format)

Where is it on the GNU emacs CVS site? I was unable to find it (but have to confess to not being interested in spending all afternoon looking for it…).

- Alan

I don’t believe its in GNU Emacs CVS, a quick search : and a look in my CVS copy of emacs seems to confirm this (so I think the page is wrong above). Aquamacs has it, as does emhacks. They both claim to be tabbar 2.0 from a quick look, I’ve got tabbar 1.3 and it seems okay with GNU Emacs 23.0.60.1 :

I’m having trouble combining tabbar with color-theme mode. If I load a color-theme at startup, it isn’t applied to tabbar. Only if I manually change the color-theme mode, using M-x color-theme-charcoal-black, is the styling applied to tabbar. If anybpdy knoqws why this may be, please comment back here. – TroelsKn

I would like to change this mode’s behaviour. I want to show only the most N recent files for each mode, which get re-ordered each time i change buffer. Would it be possible to do this? Can anyone tell me which functions should i modify? I’ve been reading tabbar.el but i am not suere where to start with.

Thanks! – Matiyam

You could follow the defadvice defined in “Add a buffer modification state indicator in the label”, and instead of adding a + sign to mark modified buffers, you could sort the list according to the buffer’s last visit time. I don’t know if the last visit time is stored somewhere. If not, add a variable to each buffer and hook a function that updates that variable with the current time to the hook that’s executed when one leaves a buffer (couldn’t find what hook it is). – js

Is there a way to stop emacs from splitting the window when opening multiple files from the command line? (i.e. “emacs file1 file2”) The tabbar makes the window splitting unnecessary, but there doesn’t seem to be any command line arguments to stop this from happening. Thanks in advance.

- Kristi

You could put something like (delete-other-windows) at the end of your .emacs or alternatively use something like: “emacs file1 file2 --eval ‘(delete-other-windows)’” Its a bit of a hack I agree, and could cause problems in odd situations but it should do the trick.

Matiyam – sounds like swbuff/swbuff-y. It’s a different interface, though, but I’ve used shift-left/right to switch buffers with swbuff for awhile. I didn’t like the re-ordering, which is what led me to tabbar…

For emacs 23.1 I have to changed above codes to get list all buffers as one group:

(setq tabbar-buffer-groups-function
(lambda ()
(list "All")))

- dixiecko

The function expects one argument; the buffer name. Here is how the example above looks with a regular expression:

Grant, should the above work in xemacs? I cannot get xemacs to force all files to a single buffer with multiple tabs. – Russell

Aquamacs tabbar work with standard emacs.Just check it out. – Emmett

Has anyone else managed to get the aquamacs tabbar mode working with gnu emacs, and could provide further instructions? Thanks - Josh

Aquamacs tabbar and even the fork doesn’t work with the recent bzr emacs. Need help! – Emmett

Tabbar is very nice, but I’ve noticed that at least on GNU Emacs v24.2.1, but when combined with setting variable scroll-conservatively to 10 and/or variable scroll-margin to 3, it breaks function next-line. That is, when I’m pressing the down key, and the cursor reaches the bottom of the window, pressing the down key again causes a sort of weird, slow, jerky scrolling down, which is not completely but almost broken. --TeemuLeisti 2012-10-17

As teemuLeisti said, I found this bug,too. When I use tabbar mode, the behavior of scrolling down becomes very weird. Two or three presses of Arrow-Down are needed to move just one line. This makes Emacs difficult to use. – Qihao 2014-01-07

This work is licensed to you under version 2 of the
GNUGeneral Public License.
Alternatively, you may choose to receive this work under any other
license that grants the right to use, copy, modify, and/or distribute
the work, as long as that license imposes the restriction that
derivative works have to grant the same rights and impose the same
restriction. For example, you may choose to receive this work under
the
GNUFree Documentation License, the
CreativeCommonsShareAlike
License, the XEmacs manual license, or
similar licenses.