I am using tabbar-mode and I love it. I have only one thing which is irritating me: the sorting order of tabs of fired windows.

As in other modes, they seem to be sorted by time opened. But in case of the dired buffers, I would prefer a sorting based on the directory structure, so that lower directories are further left, an directories higher in the directory structure further to the right. As an example, the tabs could be sorted like this:

/ | home | Username | DirectoryInUsernamesHomeDirectory | SecondUsername | ...

I am aware, that it is not possible to project a two-dimensional tree structure into a one dimensional tab-bar, but any logical sorting based on the tree structure would be favourable to a time-of-opening sorting as it is now.

Is there any way (sure there is - but my elisp knowledge is not sufficient to write it) to achieve this? I guess a custom function tab-bar-add-tab needs to be defines as here?

  • s/fired/dired/ (your spell checker is fired)
    – nispio
    Sep 25, 2014 at 15:00
  • Yup - the spell checker is dired...
    – Rainer
    Sep 25, 2014 at 17:32

1 Answer 1


Conveniently enough, sorting dired buffers alphabetically (by full path) results in exactly the behaviour you describe. So it turns out to be quite achievable.

Simply add the following snippet to your init file and everything should work.

(require 'tabbar)

(defun tabbar-add-tab (tabset object &optional append)
  "Add to TABSET a tab with value OBJECT if there isn't one there yet.
If the tab is added, it is added at the beginning of the tab list,
unless the optional argument APPEND is non-nil, in which case it is
added at the end."
  (let ((tabs (tabbar-tabs tabset)))
    (if (tabbar-get-tab object tabset)
      (let ((tab (tabbar-make-tab object tabset)))
        (tabbar-set-template tabset nil)
        (set tabset
             (if (tabbar-tab-derived-mode-p 'dired-mode tab)
                 (sort (cons tab tabs) #'tabbar-default-directory<)
               (if append
                   (append tabs (list tab))
                 (cons tab tabs))))))))

(defun tabbar-default-directory< (a b)
  "Is the `default-directory' of tab A `string<' than that of B?"
   (expand-file-name (buffer-local-value 'default-directory (car a)))
   (expand-file-name (buffer-local-value 'default-directory (car b)))))

(defun tabbar-tab-derived-mode-p (mode tab)
  "Is the major mode of TAB derived from MODE?"
  (with-current-buffer (car tab)
    (derived-mode-p mode)))

All the magic happens on the line (sort (cons tab tabs) #'tabbar-dired<) which sorts the dired tab list whenever a new tab is added.

  • Perfect - works like a charm. If I want to use the same for other modes, i.g. org-mode files, I assume I have to use (if (tabbar-tab-derived-mode-p 'org-mode tab) - but what do I have to use instead of "#'tabbar-dired<"?
    – Rainer
    Sep 25, 2014 at 9:37
  • @Rainer Now that you ask, that was a bad name for the function, so I renamed it. On your question, do you want to sort your org-mode files in exactly the same way (by the directory structure)? If so, you can use the exact same function.
    – Malabarba
    Sep 25, 2014 at 9:44
  • 1
    OK - understood - didn't realise it was a function. Thanks again.
    – Rainer
    Sep 25, 2014 at 9:47
  • 1
    For the record: I replaced (tabbar-tab-derived-mode-p 'dired-mode tab) with (or (tabbar-tab-derived-mode-p 'dired-mode tab) (tabbar-tab-derived-mode-p 'org-mode tab)) to get the same behaviour for org-mode. This can be extended for other modes as well.
    – Rainer
    Sep 25, 2014 at 10:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.