Piszę główny tryb dla języka programowania, ale chcę obsługiwać starsze wersje Emacsa. prog-mode
jest stosunkowo nowy. Chcę dziedziczyć, prog-mode
jeśli jest zdefiniowane, ale nadal robię coś sensownego w przeciwnym razie.
Jakie jest najlepsze podejście? Czy powinienem defalias
prog-mode
używać starszego Emacsena, czy może to będzie kolidować z innymi trybami, jeśli robią to samo?
major-mode
prog-mode
version-compatibilty
Wilfred Hughes
źródło
źródło
prog-mode
. W szczególności będziesz cierpieć z powodu braku wiązania leksykalnego.Odpowiedzi:
Kosztem dodatkowego wiązania symboli najwyższego poziomu jest bardzo fajne rozwiązanie, które pozwala uniknąć powtarzania
define-derived-mode
formy:Działa dobrze w każdym Emacsie> = 23. Wymyśliłem to
haml-mode
kilka lat temu IIRC i wydaje się, że rozprzestrzenił się stamtąd na kilka innych głównych trybów. Najważniejsze, codefine-derived-mode
robi makro z symbolem trybu nadrzędnego, to generowanie kodu, który wywołuje jego funkcję: w tym sensiedefalias
nowa zmienna jest dokładnie równoważna funkcji aliasu.Jednym zastrzeżeniem jest to, że może to mylić
derived-mode-p
, więc kod, który sprawdza, czy tryb, z którego wywodzisz się z trybu,prog-mode
może nie działać poprawnie. W praktyce nie spotkałem się z żadnymi problemami: zwykle taki kod się zaczepiaprog-mode-hook
, co wciąż się uruchamia.(Jak zauważa Jorgen w komentarzach,
define-derived-mode
używa równieżmode-class
właściwości z symbolu trybu rodzica idefalias
nie skopiuje jej. W chwili pisania ta właściwość wydaje się być używana tylkospecial-mode
.)Aktualizacja: w dzisiejszych czasach po prostu sugeruję wymaganie co najmniej Emacsa 24, ponieważ starsze wersje są od dawna przestarzałe.
źródło
prog-mode
, ale nie działa dla każdego trybu.define-derived-mode
kopiujemode-class
właściwość symbolu do trybu potomnego.defalias
Będzie nie przekazać tę właściwość. Jeślimode-class
ma to zastosowanie w twoim przypadku użycia, musisz skopiować / ustawić go ręcznie.mode-class
oznacza nieruchomość.tl; dr: Użyj
if
i własnej funkcji 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: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 tegoprog-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 :-))
źródło
prog-mode
starszych Emacsen? Byłoby sensu pochodzą ztext-mode
lubfundamental-mode
, jeśliprog-mode
nie jest dostępna?fboundp
najpierw, tylko zdefine-derived-mode
instrukcją? Czy zatem tryb rzeczywisty z pełną definicją można wyprowadzić z tego trybu pośredniego? W ten sposób cały tryb nie musi być definiowany dwukrotnie.fundamental-mode
jest równoważne wyprowadzaniu znil
(i faktyczniedefine-derived-mode
zastępujefundamental-mode
jenil
), chociażtext-mode
nie jest właściwe, ponieważ kod programu nie jest tekstem. Większość ustawień domyślnychtext-mode
nie ma sensu w trybach programowania poza komentarzami. Dlategoprog-mode
wprowadzono w Emacs 24.define-derived-mode
definicji wif
formie, tylko dla trybu pośredniego zamiast trybu końcowego. Zastąpiłbyśdefun
dla funkcji initdefine-derived-mode
tryb dla trybu końcowego. Nie sądzę, aby było to szczególnie korzystne. Możesz również zdefiniowaćprog-mode
siebie, jak sugeruje oryginalne pytanie, ale może to łatwo pomylić inne tryby, które polegają nafboundp
sprawdzaniu obecności tego trybu.define-derived-mode
konieczne są dwa różne stwierdzenia. Kilka lat temu wymyśliłem rozwiązanie, które opublikowałem jako osobną odpowiedź, i wydaje się, że działa dobrze zarówno w Emacs 23, jak i 24. Kod jest podobny do wielu popularnych głównych trybów.Myślę, że testowanie przy użyciu
fboundp
ma większy sens.źródło
Możesz zdefiniować makro opakowania dla
define-derived-mode
oceny jego argumentów.(Ostrzeżenie: tylko minimalnie przetestowane.)
źródło