tl; dr: Użyj if
i własnej funkcji init:
(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)))
Następnie wykonaj całą inicjalizację trybu w your-cool-init
.
Dłuższe wyjaśnienie:
Problem polega na tym, że oficjalnym sposobem pisania pochodnego trybu głównego jest użycie define-derived-mode
makra:
(define-derived-mode your-cool-mode prog-mode ...)
W starszych Emacsen (wcześniejszych niż 24) to się psuje, kiedy prog-mode
. I nie możesz go użyć (if (fboundp 'prog-mode) ...)
, ponieważ makro oczekuje dosłownego symbolu i zacytuje go dla ciebie w rozszerzeniu.
define-derived-mode
używa rodzica na wiele sposobów. Aby z nich skorzystać, musisz skopiować wszystkie z nich we własnej definicji trybu, a to zarówno żmudne, jak i podatne na błędy.
Zatem jedynym sposobem jest użycie dwóch różnych define-derived-mode
instrukcji, w zależności od tego prog-mode
, czy istnieje, czy nie. To pozostawia problem z dwukrotnym pisaniem kodu inicjalizacji. Co jest oczywiście złe, więc wyodrębnij to do jego własnej funkcji, jak opisano powyżej.
(Najlepszym rozwiązaniem jest oczywiście porzucenie wsparcia dla 23.x i użycie zakresu leksykalnego. Ale myślę, że już rozważałeś i zrezygnowałeś z tej opcji :-))
prog-mode
. W szczególności będziesz cierpieć z powodu braku wiązania leksykalnego.