Tonight I noticed that I had over 200 buffers open in emacs. I’ve been programming a lot in Python recently, so many of them are in Python mode. I wondered how many Python files I had open, and I counted them by hand. About 90. I then wondered how many were in Javascript mode, in RST mode, etc. I wondered what a histogram would look like, for me and for others, at times when I’m programming versus working on documentation, etc.

Because it’s emacs, it wasn’t hard to write a function to display a buffer mode histogram. Here’s mine:

235 buffers open, in 23 distinct modes 91 python +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 47 fundamental +++++++++++++++++++++++++++++++++++++++++++++++ 24 js2 ++++++++++++++++++++++++ 21 dired +++++++++++++++++++++ 16 html ++++++++++++++++ 7 text +++++++ 4 help ++++ 4 emacs-lisp ++++ 3 sh +++ 3 makefile-gmake +++ 2 compilation ++ 2 css ++ 1 Buffer-menu + 1 mail + 1 grep + 1 completion-list + 1 vm + 1 org + 1 comint + 1 apropos + 1 Info + 1 vm-summary + 1 vm-presentation +

Tempting as it is, I’m not going to go on about the heady delights of having a fully programmable editor. You either already know, or you can just drool in slack-jawed wonder.

Unfortunately I’m a terrible emacs lisp programmer. I can barely remember a thing each time I use it. But the interpreter is of course just emacs itself and the elisp documentation is in emacs, so it’s a really fun environment to develop in. And because emacs lisp has a ton of support for doing things to itself, code that acts on emacs and your own editing session or buffers is often very succinct. See for example the save-excursion and with-output-to-temp-buffer functions below.

( defun buffer-mode-histogram ( )

"Display a histogram of emacs buffer modes."

( interactive )

( let * ( ( totals ‘ ( ) )

( buffers ( buffer- list ( ) ) )

( total-buffers ( length buffers ) )

( ht ( make-hash-table : test ‘ equal ) ) )

( save-excursion

( dolist ( buffer buffers )

( set-buffer buffer )

( let

( ( mode- name ( symbol- name major-mode ) ) )

( puthash mode- name ( 1 + ( gethash mode- name ht 0 ) ) ht ) ) ) )

( maphash ( lambda ( key value )

( setq totals ( cons ( list key value ) totals ) ) )

ht )

( setq totals ( sort totals ( lambda ( x y ) ( > ( cadr x ) ( cadr y ) ) ) ) )

( with-output-to-temp-buffer "Buffer mode histogram"

( princ ( format "%d buffers open, in %d distinct modes



"

total-buffers ( length totals ) ) )

( dolist ( item totals )

( let

( ( key ( car item ) )

( count ( cadr item ) ) )

( if ( equal ( substring key -5 ) "-mode" )

( setq key ( substring key 0 -5 ) ) )

( princ ( format "%2d %20s %s

" count key

( make-string count ?+ ) ) ) ) ) ) ) )



Various things about the formatting could be improved. E.g., not use fixed-width fields for the count and the mode names, and make the + signs indicate more than one buffer mode when there are many.