Monday, April 30, 2007

Update: [2018-10-29] As this blog post is over 10 years old, I have posted my configuration as of 2018

Tabs to show overlapping windows are becoming more common these days, especially in terminals, browsers, and chat programs. The idea is that a single window can contain several … buffers. Emacs already has this, and has had this for a long time. It's just that by default Emacs doesn't have visible tabs to show the buffers. XEmacs and SXEmacs can show tabs with “buffer tabs”; for GNU Emacs 21 you need to install TabBar mode (thanks to Jemima for finding this), which gives you tabs like this:

Well, it doesn't look like that by default. The standard settings give each tab a 3d button appearance. I wanted something simpler, so I changed the settings:

;; Note: for tabbar 2.0 use ;; tabbar-default not tabbar-default-face, ;; tabbar-selected not tabbar-selected-face, ;; tabbar-button not tabbar-button-face, ;; tabbar-separator not tabbar-separator-face ( set-face-attribute ' tabbar-default-face nil :background "gray60" ) ( set-face-attribute ' tabbar-unselected-face nil :background "gray85" :foreground "gray30" :box nil ) ( set-face-attribute ' tabbar-selected-face nil :background "#f2f2f6" :foreground "black" :box nil ) ( set-face-attribute ' tabbar-button-face nil :box ' ( :line-width 1 :color "gray72" :style released-button ) ) ( set-face-attribute ' tabbar-separator-face nil :height 0.7 ) ( tabbar-mode 1 ) ( define-key global-map [ ( alt j ) ] ' tabbar-backward ) ( define-key global-map [ ( alt k ) ] ' tabbar-forward )

This makes the currently selected tab match my default background ( #f2f2f6 ), removes the 3d borders, and adds a bit of space between the tabs. I also define Alt + J and Alt + K to switch tabs; I use the same keys in other tabbed apps, because they're easier to type than moving my hands to the arrow keys.

TabBar-mode looks neat, but I'm not sure how useful it will be. In Emacs I have lots of buffers—more than will fit as tabs. The main thing I like so far are the keys for cycling between related buffers, but as the number of buffers grows it becomes faster to switch directly to the buffer I want.

Edit: [2010-11-20] I like tabbar-mode but I also find myself using other buffer switching quite a bit. I'm using tabbar within a project, and ido-switch-buffer for moving between projects. I've changed the tabbar groups to show only buffers in the same directory:

(defun my-tabbar-buffer-groups (buffer) "Put files in the same directory into the same tab bar" (with-current-buffer (get-buffer buffer) (list (expand-file-name default-directory)))) (setq tabbar-buffer-groups-function 'my-tabbar-buffer-groups)

Update: [2017-09-24] I wanted to make the tabs look more like tabs in other apps, so I used powerline's "wave" separators with tabbar:

(defvar my/tabbar-left "/" "Separator on left side of tab") (defvar my/tabbar-right "\\" "Separator on right side of tab") (defun my/tabbar-tab-label-function (tab) (powerline-render (list my/tabbar-left (format " %s " (car tab)) my/tabbar-right))) (require 'powerline) (setq my/tabbar-left (powerline-wave-right 'tabbar-default nil 24)) (setq my/tabbar-right (powerline-wave-left nil 'tabbar-default 24)) (tabbar-mode 1) (setq tabbar-tab-label-function #'my/tabbar-tab-label-function)))

Note that tabbar resets tabbar-tab-label-function after you run (tabbar-mode 1) so you need to make you set it after you've already activated tabbar-mode.

Labels: emacs