Unique buffer names in Emacs

May 9, 2016

When I work on large codebase done by more than one developer, I often find this pattern:

src/clj/module/submodule1/user.clj
src/clj/module/submodule1/db.clj
src/clj/module/submodule2/user.clj
src/clj/module/submodule2/db.clj
src/clj/module/submodule3/user.clj

Of course, this isn't the case with Java or Clojure only; this can be found in almost any larger project no matter what language is used. After all, folders are invented to keep the files under different namespaces, right?

In Emacs, when you open these files and display them in ibuffer or buffer-menu, they will end up with this:

 MR Name             Size Mode             Filename/Process
 -- ----             ---- ----             ----------------
[Default]
    user.clj<1>     19889 Clojure          src/clj/module/submodule1/user.clj
    user.clj<2>      4821 Clojure          src/clj/module/submodule3/user.clj
    user.clj<3>      4821 Clojure          src/clj/module/submodule2/user.clj
    db.clj<1>        4821 Clojure          src/clj/module/submodule1/db.clj
    db.clj<2>        4821 Clojure          src/clj/module/submodule2/db.clj

There are couple of problems with this:

  • unless you check that Filename/Process column, you'd have no idea where this file came from
  • completion engines like ido-mode (or modes like evil) will give you to choose between numbered buffers (e.g. db.clj<1> and db.clj<2>), which isn't much usable when you have large number of files with the same name

Shame on me, today I learned about uniquify module which deals with this problem; it is shipped with Emacs for years (!!) and is enabled by default from 24.4 version. This small chunk will do all the magic I always need:

;; replace 'ibuffer' with 'buffer-menu' if you are using buffer-menu
;; for displaying buffer list
(eval-after-load "ibuffer"
  '(progn
     (require 'uniquify)
     (setq uniquify-buffer-name-style 'forward)))

In short, buffer names will be more readable now:

 MR Name                     Size Mode             Filename/Process
 -- ----                     ---- ----             ----------------
[Default]
    submodule1/user.clj     19889 Clojure          src/clj/module/submodule1/user.clj
    submodule3/user.clj      4821 Clojure          src/clj/module/submodule3/user.clj
    submodule2/user.clj      4821 Clojure          src/clj/module/submodule2/user.clj
    submodule1/db.clj        4821 Clojure          src/clj/module/submodule1/db.clj
    submodule2/db.clj        4821 Clojure          src/clj/module/submodule2/db.clj

Sweet!