Category: elisp

Emacs: Custom columns for Ibuffer

Emacs 23.2 is out! To celebrate, I'll write (yet) another Emacs post. Please forgive the fact that the content has nothing to do with version 23.2 in particular (you can read about all new stuff in the NEWS file (C-h n)).

I'm very fond of the Ibuffer package. It lists all your buffers, and allows you to sort, filter, and group them as you please. You can operate on multiple buffers by marking a subset and then calling a command (think "delete" or "replace-regexp"). Amazing! Ibuffer's got it all.

I was reading Ibuffer's source to see if I could add my own information to the buffer listing. Specifically, I wanted to indicate that a file was part of my "project" (as defined by mk-project). Ibuffer did not disappoint. It was trivial to create a new custom column with the define-ibuffer-column macro.

In the "screenshot" below, I have a mk-project defined which includes all the files in my ~/elisp directory. You'll see a "p" next to each of these files.

 MRP  Name                                Size Mode             Filename/Process
 ---  ----                                ---- ----             ----------------
[ Default ]
      z.clj                               2210 Clojure          ~/z.clj
      tmp.txt                             2915 Text             ~/tmp.txt
   p  projects.el                         3127 Emacs-Lisp       ~/elisp/projects.el
   p  mk-utils.el                         9968 Emacs-Lisp       ~/elisp/mk-utils.el
   p  basic.el                            7245 Emacs-Lisp       ~/elisp/basic.el
...

In the code below, I create a column named mk-proj-col, the column heading of which is simply "P", and if a particular buffer is a part of my project, it will print "p" next to it.

(defun mk/proj-buffer-p (b)
  "Is the buffer `b' part of the project?"
  (and mk-proj-name 
       (or (mk-proj-buffer-p b)
           (string= (buffer-name b) mk-proj-fib-name)
           (string= (buffer-file-name b) mk-proj-tags-file))))

(define-ibuffer-column mk-proj-col
  (:name "P")
  (if (mk/proj-buffer-p buffer) "p" ""))

;; Define 3 formats, each including the new mk-proj-col
;; column. Switch formats with ibuffer-switch-format (bound to "`").
(setq ibuffer-formats
      '((mark modified read-only              
              (mk-proj-col 2 2 :left :elide) " "
              (name 30 30 :left :elide) " "
              (size 9 -1 :right) " "
              (mode 16 16 :left :elide) " "
              filename-and-process)
        (mark modified read-only
              (mk-proj-col 2 2 :left :elide) " "
              (name 45 -1 :left) " "
              filename-and-process)
        (mark modified read-only
              (mk-proj-col 2 2 :left :elide) " "
              filename-and-process)))

And it was even easier to define a filter command that displays just the files in my project.

(define-ibuffer-filter project
  "Toggle current view to buffers in the defined mk-project."
  (:description "mk-project")
  (mk/proj-buffer-p buf))

(define-key ibuffer-mode-map (kbd "/ k") 'ibuffer-filter-by-project)

Technorati tags for this post:

Announce: mk-project 1.4.0

I've uploaded a new version of mk-project to the usual, places.

Enhancements

  • project-find-file-ido now displays relative filenames (relative to the project directory) rather than the absolute filenames. This cuts the visual clutter way down.
  • A brand new project function, project-multi-occur, searches all open project files for a regex using multi-occur.
  • A message is printed when the project is finished loading.
  • A new README file provides details of all the configuration options.

Bug Fixes

  • Now quoting filename arguments used in find commands. Filenames with spaces, for example, now won't break the find commands we use to generate TAGS or the index file.

Enjoy!

Technorati tags for this post:

Announce: mk-project 1.3.1

Version 1.3.1 of mk-project.el is available from github or the Emacs Wiki. David Findlay reported that project-grep and project-ack where running from the project basedir's parent directory, not the project basedir. This behavior was possible on certain versions of Emacs if the project's basedir didn't include a trailing slash -- like this:

(project-def "test-project"
  ((basedir "/home/me/test-project") ; no trailing slash
   ...
   ))

The new version ensures that the trailing slash is appended to basedir when it is used as the default-directory value.

Thanks much to David for the bug report and helping me test potential solutions!

Technorati tags for this post:

mk-project.el v1.2.1

I've pushed mk-project version 1.2.1 to both the Emacs Wiki and github. It fixes a bug that was preventing mk-project from killing dired buffers open to a project's basedir (or a subdirectory of the basedir) when the project was closed (and the user elects to close all project files). You can now also expect dired buffers belonging to the project to be restored when the project is re-opened.

Thanks much to aleblanc@cotse.net for the bug report and code.

For more info on mk-project, see its homepage.

Technorati tags for this post:

< Future 10 | Past 10 >