tl;dr: Use if
and your own init function:
(if (fboundp 'prog-mode)
(define-derived-mode your-cool-mode prog-mode "Cool"
"Docstring"
(your-cool--init))
(define-derived-mode your-cool-mode nil "Cool"
"Docstring"
(your-cool--init)))
Then do all the mode's initialization in your-cool-init
.
Longer explanation:
The problem is that the official way of writing a derived major mode is to use the define-derived-mode
macro:
(define-derived-mode your-cool-mode prog-mode ...)
On older Emacsen (pre-24), this breaks when prog-mode
. And you can't use (if (fboundp 'prog-mode) ...)
there because the macro expects a literal symbol, and will quote it for you in the expansion.
define-derived-mode
uses the parent in a multitude of ways. You'd need to copy all of those in your own mode definition to make use of them, and that's both tedious and error-prone.
So the only way is to use two different define-derived-mode
statements, depending on whether prog-mode
exists or not. That leaves you with the problem of writing your initialization code twice. Which is of course bad, so you extract that into its own function, as described above.
(The best solution is of course to drop support for 23.x and use lexical scoping. But I guess you already considered and dropped that option. :-))