I have been using Emacs since version 18. Emacs Lisp isn't my routine programming language, but years ago I invested some time studying it to the point of creating a .emacs that's better (for me) than any GUI IDE to date.
That was a one-time effort and since then, I forgot completely how to program in lisp.
Alas, every time I upgrade my Emacs (18 > 19 > 20 > 21 > 22 > 23), something in my .emacs breaks, and I end up spending way too many hours (sometimes days) fixing these.
In many other languages I program routinely, it is possible to write code that never becomes obsolete. In emacs, on the other hand, I can never predict how things will change. For example [M-TAB]
that used to work up until version 21.4.1, no longer works in version 23 and must be replaced with "\M-\t"
. Another example is dired-omit-toggle
that used to work in version 21 but stopped working in version 22, being replaced by dired-omit-mode
.
Now, I know that if a .emacs doesn't do much, it's possible to write "an almost empty" .emacs that can (probably) stay compatible with future versions.
But my .emacs is huge, designed to run on many different operating systems (and their different flavors, editions and versions, including non-GUI systems) without a single change. I wish there was a core-API or subset that is guaranteed to always work.
Is there really such a way to write a .emacs that will always stay upward compatible?
If so, where can I find a "cook book" or authoritative guidelines for accomplishing this?
Use (when (boundp 'some-variable) …)
or (when (fboundp 'some-function) …)
around any piece of code that relies on a specific feature. (While you're at it, start with (require 'cl)
for those older versions that don't have when
built-in.)
When all else fails, discriminate on emacs-major-version
, emacs-minor-version
and running-xemacs
(defined as (string-match "XEmacs\\|Lucid" emacs-version)
).
Avoid syntax and library functions that are only supported in newer versions.
It's rare that something breaks when you stick to documented interfaces. So try to look for a way to do things that's mentioned in the manual, and only fall back to modifying some random non-customizable variable if you see no other way. In my experience there is always a reasonably easy way to get something to work in all versions (at least with GNU Emacs, XEmacs is sometimes harder to please) if you allow the occasional conditional.
For example, "\e\t"
has always worked for M-TAB
. With dired-omit-mode
, fall back to dired-omit-toggle
if the former does not exist:
(set (if boundp 'dired-omit-mode 'dired-omit-mode 'dired-omit-toggle) t)
Yes, it's slightly painful, but not as dramatic as you make it out to be. I maintain a .emacs
that works with anything since 19.23 (IIRC, it's been a while since I tested with anything older than 19.34) on all of DOS, Windows and unix. Compatibility with Windows is in fact more of a burden than keeping up with GNU Emacs version changes.
As for a cookbook, well, most differences between versions have to do with features that aren't very widely used (otherwise the maintainers would give more importance to strict upward compatibility). Since Emacs is big, there's undoubtedly plenty of it that you use but the cookbook writer wouldn't have heard of. You'll have to play it by ear. Fortunately it's not too hard.
Since Its impossible to predict future changes of anything, no one can guarantee the future compatibility.
I think the following points are few of many general ways to make it easy to maintain .emacs or init.el (which I am practicing right now.)
use when
to load specific customizations for a version of emacs.
for eg:
(when (= emacs-major-version 24)
;;load my settings for 24
)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With