Estoy escribiendo un modo principal para un lenguaje de programación, pero quiero admitir versiones anteriores de Emacs. prog-mode
Es relativamente nuevo. Quiero heredar de prog-mode
si está definido, pero de lo contrario seguiré haciendo algo sensato.
¿Cuál es el mejor enfoque? ¿Debo defalias
prog-mode
usar Emacsen más antiguo, o eso interferirá con otros modos si hacen lo mismo?
major-mode
prog-mode
version-compatibilty
Wilfred Hughes
fuente
fuente
prog-mode
. En particular, sufrirá la falta de unión léxica.Respuestas:
A costa de un enlace de símbolo de nivel superior adicional, hay una solución muy clara que evita repetir el
define-derived-mode
formulario:Funciona bien en cualquier Emacs> = 23. Se me ocurrió esto hace
haml-mode
un par de años IIRC, y parece haberse extendido desde allí a varios otros modos principales. Lo principal que hace ladefine-derived-mode
macro con el símbolo del modo padre es generar código que llama a su función: en este sentido,defalias
hace que la nueva variable sea exactamente equivalente a la función con alias.Una advertencia es que esto puede confundir
derived-mode-p
, por lo que el código que verifica si su modo se derivaprog-mode
puede no funcionar correctamente. En la práctica, no he encontrado ningún problema: es más habitual que se conecte dicho códigoprog-mode-hook
, que aún se ejecuta.(Como Jorgen señala en los comentarios,
define-derived-mode
también usa lamode-class
propiedad del símbolo del modo principal ydefalias
no la copia. Al momento de escribir, esta propiedad solo parece ser utilizada paraspecial-mode
).Actualización: en estos días, simplemente sugiero que se requiera al menos Emacs 24, ya que las versiones anteriores son obsoletas durante mucho tiempo.
fuente
prog-mode
, pero no funcionará para todos los modos.define-derived-mode
copia lamode-class
propiedad del símbolo en el modo secundario. Eldefalias
será no transferir esta propiedad. Simode-class
es relevante para su caso de uso, debe copiarlo / configurarlo manualmente.mode-class
denota la propiedad.tl; dr: Use
if
y su propia función init:Luego haga toda la inicialización del modo en
your-cool-init
.Explicación más larga:
El problema es que la forma oficial de escribir un modo principal derivado es usar la
define-derived-mode
macro:En Emacsen anterior (anterior a 24), esto se rompe cuando
prog-mode
. Y no puede usarlo(if (fboundp 'prog-mode) ...)
allí porque la macro espera un símbolo literal y lo citará en la expansión.define-derived-mode
usa el padre de muchas maneras. Debería copiarlos en su propia definición de modo para utilizarlos, y eso es tedioso y propenso a errores.Entonces, la única forma es usar dos
define-derived-mode
declaraciones diferentes , dependiendo de siprog-mode
existe o no. Eso te deja con el problema de escribir tu código de inicialización dos veces. Lo cual, por supuesto, es malo, por lo que extrae eso en su propia función, como se describe anteriormente.(La mejor solución es, por supuesto, abandonar el soporte para 23.xy usar el alcance léxico. Pero supongo que ya consideró y eliminó esa opción. :-))
fuente
prog-mode
Emacsen anterior? ¿Tendría sentido derivar detext-mode
ofundamental-mode
siprog-mode
no está disponible?fboundp
primero, solo con ladefine-derived-mode
declaración? Entonces, ¿el modo real con definición completa puede derivarse de ese modo intermedio? De esta forma, no es necesario definir todo el modo dos veces.fundamental-mode
es equivalente a derivar denil
(y de hecho,define-derived-mode
reemplazafundamental-mode
connil
), aunquetext-mode
no es apropiado, ya que el código del programa no es texto. La mayoría de las configuraciones predeterminadastext-mode
no tienen sentido en los modos de programación fuera de los comentarios. Por esoprog-mode
se introdujo en Emacs 24.define-derived-mode
definiciones en unaif
forma, solo para el modo intermedio en lugar del modo final. Reemplazaría ladefun
función de inicio por unadefine-derived-mode
para el modo final. No creo que esto sea particularmente preferible. También podría definirprog-mode
uno, como sugiere la pregunta original, pero eso puede confundir fácilmente a otros modos en los que confíanfboundp
para verificar la presencia de ese modo.define-derived-mode
sean necesarias dos declaraciones diferentes . Hace un par de años se me ocurrió la solución que publiqué como respuesta por separado, y parece funcionar bien en Emacs 23 y 24. El código como se usa en varios modos principales populares.Creo que probar usando
fboundp
tiene más sentido.fuente
Puede definir una macro de contenedor para
define-derived-mode
que evalúe sus argumentos.(Advertencia: solo mínimamente probado).
fuente