2

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?

Chris R
  • 17,546
  • 23
  • 105
  • 172
  • I recommend you to have a look at this [post](http://emacs-fu.blogspot.com/2008/12/using-packages-functions-only-if-they.html) on the great blog ["Emacs Fu"](http://emacs-fu.blogspot.com/). 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 Mar 22 '10 at 15:24

3 Answers3

2

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.
  • 10,764
  • 7
  • 45
  • 59
  • 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 Mar 22 '10 at 15:27
  • 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 Mar 23 '10 at 16:16
0

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

offby1
  • 6,767
  • 30
  • 45
  • It touches on some functions, but it doesn't seem to have all of the information I'm looking for. – Chris R Mar 22 '10 at 15:25
  • 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-mode This can be pretty slow :-| – offby1 Mar 26 '10 at 16:19
0

It's usually better practice to test the existence of the function or variable you want to use, rather than test the Emacs version. Use fboundp and boundp, for example. Occasionally it makes sense to check featurep, but there again it is usually better to use fboundp or boundp.

Drew
  • 29,895
  • 7
  • 74
  • 104