views:

151

answers:

3

I want to write a .emacs that uses as much of the mainline emacs functionality as possible, falling back gracefully when run under previous versions. I've found through trial and error some functions that didn't exist, for example, in emacs 22 but now do in emacs 23 on the rare occasion that I've ended up running my dotfiles under emacs 22. However, I'd like to take a more proactive approach to this, and have subsets of my dotfiles that only take effect when version >= <some-threshold> (for example). The function I'm focusing on right now is scroll-bar-mode but I'd like a general solution.

I have not seen a consistent source for this info; I've checked the gnu.org online docs, the function code itself, and so far nothing. How can I determine this, without keeping every version of emacs I want to support kicking around?

+2  A: 

I cannot answer your question directly, but one technique I use is to check the functionp function that tells me if a function exists.

e.g.

(if (load "completion" t)
  (progn
    (initialize-completions)
    (if (functionp 'dynamic-completion-mode)
      (dynamic-completion-mode) ; if exists
      (completion-mode)         ; otherwise use old version
    )
  ) ; progn
) ; if

update: adding version specific macros

In addition to using functionp I also have some version specific macros:

(defmacro GNU_EMACS_21 (&rest stuff)
   (list 'if (string-match "GNU Emacs 21" (emacs-version)) (cons 'progn stuff)))
(defmacro GNU_EMACS_20 (&rest stuff)
  (list 'if (string-match "GNU Emacs 20" (emacs-version)) (cons 'progn stuff)))
(defmacro GNU_EMACS_19 (&rest stuff)
  (list 'if (string-match "GNU Emacs 19" (emacs-version)) (cons 'progn stuff))) 
(defmacro WINSYS_X (&rest stuff)
  (list 'if (eq window-system 'x) (cons 'progn stuff)))
(defmacro WINSYS_W32 (&rest stuff)
  (list 'if (eq window-system 'w32) (cons 'progn stuff)))
(defmacro WINSYS_NIL (&rest stuff)
  (list 'if (eq window-system nil) (cons 'progn stuff)))
(defmacro SYSTYPE_LINUX (&rest stuff)
  (list 'if (string-match "linux" (symbol-name system-type)) (cons 'progn stuff)))

I can then use these:

(GNU_EMACS_21
  (if (load "cua" t)
    (CUA-mode t)
  )
)
(WINSYS_NIL ; when running in text mode
  (push (cons 'foreground-color "white") default-frame-alist)
  (push (cons 'background-color "black") default-frame-alist)
  (push (cons 'cursor-color "cyan") default-frame-alist)
  (push (cons 'minibuffer t) default-frame-alist)
)

I'm guessing you already know this, however; and questions like "when did CUA mode get included with Emacs" are difficult to answer..

PP
This is the approach I'm using right now, but I don't like it; I have to repeat the same check over and over again. I'd rather group things by version than by missing capability.
Chris R
Yeah, you have a tidier way of expressing them, but the fundamental concepts are the same. I think, however, that your guess as to the difficulty of answering the core question is on the button. I'll keep this around for another week or so and then if I haven't seen an answer I'll have to accept your "It can't be done" answer.
Chris R
A: 

The "NEWS" files (accessible via C-h N) may give hints as to when functions were introduced.

offby1
It touches on some functions, but it doesn't seem to have all of the information I'm looking for.
Chris R
Yep. Another way might be to grep the ChangeLog files; you _should_ find entries like "new function: blah-blah".The authoritative way to get this information is probably to examine the revision-control logs, but that can take some effort, particularly if you're not familiar with bzr (or CVS or git). But anyway, here's how I'd do it (if I were curious about the function "auto-revert-tail-mode", for example):* git clone git://repo.or.cz/emacs.git* cd emacs* git log -Sauto-revert-tail-modeThis can be pretty slow :-|
offby1
+1  A: 

I recommend you to have a look at this post on the great blog "Emacs Fu". It's shows an approach similar to the one suggested by PP, but a bit more general. I use a similar approach myself when dealing with such issues.

Bozhidar Batsov