2008-10-08

Creating a small addition of functionality to emacs behaviour.

I thought it might be a nice thing to illustrate what a lot of people really like about emacs with a small example of a little added functionality that I implemented earlier today.

There's a function called "kill-some-buffers", which steps through your buffer list (the list of open editing areas, most likely mainly files) and asks you if you want to kill them. This is useful when you find yourself with a whole bunch of buffers open, some of which you haven't touched for a while - and I've been using it lately.

I wanted to be able to mark certain buffers as "this is not getting killed by kill-some-buffers". Looking at its documentation, it doesn't say that it supports this functionality (C-h f kill-some-buffers). Looking at its code confirms this (click "files.el" in the output of C-h f). It's a short function, although if you're not familiar with a lisp, this may look like nonsense. If you're familiar with a lisp it'll be fairly obvious, and if you're passingly familiar with elisp you shouldn't have a problem reading it.

It just walks through the list of open buffers, performs some checks, lets you know whether they're modified or unmodified and asks if you want to kill them or not, taking the appropriate action.

Rather than modify the emacs source, I copied the body of kill-some-buffers, and added a variable and another utility function.

(defvar kept-buffers nil
"A list of buffers to never kill when running `limited-kill-some-buffers'")

(defun add-to-kept-buffers (buffername)
(interactive "bAdd to kept buffers list: ")
(setq kept-buffers
(append kept-buffers (list buffername))))

The line "bAdd...." tells interactive that it expects a buffername (which comes with autocompletion, and is just a taste of what you can do with interactive....). Interactive itself tells emacs that the function can be called by a keystroke, like M-x add-to-kept-buffers.

The only change to what used to be the body of kill-some-buffers is a single check after the others that it performs:
(not (member name kept-buffers))
The only thing I might change in the future is pruning of the kept-buffers list - which can be easily done by defining "advice" on the function kill-buffer to check to see if the buffer being killed is in the kept-buffers list, and if it is to remove it from it, but kill-buffer is a "primitive" function (written in C), and defining advice on those is generally frowned upon. I want to see if there's a more appropriate way to do that cleanup before doing that. I can always manually prune the list if it gets too large. Also, right now it seems like if I add a file to the kept-buffers list, I'm probably going to want to keep that file there for a while (if I kill the buffer, and then re-open the file, I want the restriction to stay).

If I had decided to modify the files.el source file, this would have been a 7 line change. Granted, this is a pretty trivial change - but the ease with which it was performed is amazing. A little bit of reading the provided (and high quality) documentation (through C-h i), and a little bit of reading through the source, and it's possible to totally bend the editor to your whim.

So a few minutes of coding, and something that was a minor annoyance to me about one functions performance is solved.

No comments:

Post a Comment