Wednesday, December 26, 2012

An emacs configuration smell

Have you ever seen code that just looked slightly wrong?  Like a function that takes in an argument that doesn't seem relevant to the task at hand, or a class with an overly generic name like "Utilities"?  That's what some people call "code smell".  Something doesn't seem right, and you don't know exactly what it is.  All you know is that something is rotten.

There's a "code smell" I've found in my own emacs customization code.  It's anywhere where there are several functions all related to the same thing.  Whenever this happens, I realize that an emacs package is trying to be born.  Whatever I'm doing is more than trivial, and usually it is of some use to someone else. It's worthwhile to see if someone has already tried to solve this problem, or if no one has, to try and solve it in a proper way yourself.  The proper way would be to make an actual project of it, put it on github, and get it included in MELPA or some other ELPA.

For example, a few years ago, I noticed a cool vi command as I watched a colleague work.  It cleared out everything between quotes, or parenthesis, or any kind of delimiter.  I did some looking around at the time, but didn't see anything out that was relevant.  So I implemented it myself in my initialization file.  It was about 30 or so lines of code, nothing too gigantic.  But since then the great package expand-region (available in MELPA) came out, and it basically can easily do everything I was doing.  So I got to delete all that code, and replace it with:

(defun ash-clear ()
  (interactive)
  (require 'expand-region)
  (er/expand-region 1)
  (kill-region (region-beginning) (region-end))
  (er/expand-region 0))

This is much simpler, clearer, and frankly it works much better than the half-assed thing I put together.  But if this package hadn't existed, it probably would be worth my while to create it. In the process of doing so, I'd inevitably make it much better, as well as making it public so that other people can take it and possibly even contribute.

So I advise everyone to look through their personal initialization files.  Are there packages in there that need to come out?  Are they code that can be simplified by using someone else's package? If something in your emacs initialization is worth spending more than a few lines of code doing, it's worth doing right, and for everyone.

3 comments:

Magnar said...

Taking your idea a step further, there's also change-inner that is based on expand-region which does exactly what you wanted. :-) https://github.com/magnars/change-inner.el

rawshark said...

thanks magnar! I had just started using zap-to-char to accomplish this a week ago, change-inner is much cleaner

Andrew Hyatt said...

Good tip, it does do (almost) exactly what I want. I may keep around the old version, though, since it saves a keystroke by defaulting to the smallest region possible, which is almost always what I want.

But change-inner and outer seem like good things in their own right. I'll put them in and start using them, and see how it feels. Thanks, Magnar!