Elisp es un lenguaje interpretado. Puede poner código específico de la versión en su .emacs
, pero protegerlo probando en el momento de la carga que está funcionando en la versión correcta.
(if (is-new-feature-available)
(shiny-new-feature)
(old-less-nifty-feature))
Este código funcionará en todas las versiones porque (shiny-new-feature)
solo se evalúa cuando (is-new-feature-available)
devuelve verdadero. Gran parte de esta respuesta está dedicada a cómo implementarla (is-new-feature-available)
.
Lidiando con diferentes conjuntos de características
Es mejor probar si hay una función disponible que probar la versión de Emacs. A veces, la función puede estar disponible como un paquete opcional. Si desea ejecutar código en XEmacs u otra variante de Emacs, es posible que haya adquirido las mismas características en diferentes versiones. Use la función boundp
para probar si una variable está disponible y fboundp
para probar si una función está disponible.
Por ejemplo, el siguiente fragmento vincula una tecla para alternar visual-line-mode
si está disponible, y de lo longlines-mode
contrario.
(global-set-key "\eml" (if (fboundp 'visual-line-mode)
'visual-line-mode
'longlines-mode))
A veces, en lugar de probar la función, es más fácil ejecutar un pequeño fragmento de código e ignorar cualquier error debido a funciones indefinidas, argumentos no válidos, etc. No haga esto para grandes cantidades de código, ya que esto hará que su código sea muy Difícil de depurar.
Por ejemplo, no quiero ver una barra de herramientas. Las versiones anteriores de Emacs no los tenían en absoluto. GNU Emacs y XEmacs agregaron esa característica de diferentes maneras y la convirtieron en la predeterminada. Así es como los apago. La set-specifier
función es específica de XEmacs y default-toolbar-visible-p
específica de las versiones recientes de Emacs; el uso condition-case
se encarga de ambos requisitos. GNU Emacs proporciona una función dedicada, así que simplemente pruebo si esa función está disponible.
;; For XEmacs
(condition-case nil
(set-specifier default-toolbar-visible-p nil)
(error nil))
;; For GNU Emacs
(if (fboundp 'tool-bar-mode)
(tool-bar-mode 0))
Algunos nombres de caras cambian sobre las versiones. Use facep
para probar la disponibilidad de un nombre de rostro.
(let ((face (if (facep 'mode-line) 'mode-line 'modeline)))
(set-face-background face …))
A veces es posible que desee cargar un paquete agradable si está presente, y no hacer nada si el paquete no está disponible. require
tiene un argumento opcional para eso.
(require 'tex-site nil t) ;; Load AUCTeX if available
Este argumento se introdujo en GNU Emacs 20.4 y no está disponible en XEmacs, por lo que si desea retroceder tanto, tendrá que envolverlo condition-case
o usarlo load
(que no verifica las bibliotecas ya cargadas) .
Limite las dependencias de la versión a las características de nivel de usuario. No utilice las funciones de programación más nuevas que no están disponibles en todas las versiones que desea admitir: tendrá que proporcionar una versión de compatibilidad para versiones anteriores, y es más fácil mantener una versión única.
A veces necesita una función en muchos lugares, y está disponible en todas las implementaciones que le interesan, pero de una manera diferente. Este es principalmente el caso si desea admitir XEmacs y GNU Emacs: tenían una tendencia frustrante de copiar las características de los demás, pero no su interfaz. En este caso, definir una función de compatibilidad es más conveniente que probarlo en el punto de uso.
Por ejemplo, el siguiente código define una función que devuelve el sistema de ventanas del marco actual, la forma moderna de GNU, la forma moderna de XEmacs y la forma antigua cuando no se pueden combinar marcos de terminal y GUI en la misma instancia.
(defalias 'compat-window-system
(cond
((fboundp 'window-system) #'window-system)
((fboundp 'device-type)
(lambda (&optional frame)
(device-type (frame-device frame))))
(t
(lambda (&optional frame) window-system))))
Dependencias del entorno
No hay mucho código que deba depender de la plataforma. La variable system-type
indica el sistema operativo. Lo uso exclusivamente para activar algunos hacks para ms-dos
(sí, mis archivos son tan viejos) y windows-nt
.
Es posible que desee agregar directorios a su ruta de búsqueda ejecutable ( PATH
), pero eso suele hacerse mejor fuera de Emacs, en su .profile
sistema tipo Unix y a través del panel de control en Windows. Para probar si hay un programa externo disponible, llame al executable-find
.
Para el código que necesita actuar de manera diferente dependiendo del tipo de GUI, si lo hay, verifique window-type
o sus sucesores (ver arriba).
Archivos de inicialización
Para obtener la máxima compatibilidad, ingrese su código ~/.emacs
. GNU Emacs comenzó a buscar en la ~/emacs.d
versión 22. XEmacs comenzó a buscar ~/.xemacs
en la versión 21.4. Un enfoque alternativo es colocar ~/.emacs
y finalizar el código de compatibilidad cargando su archivo principal. Colóquelo en (setq load-home-init-file t)
algún lugar para evitar que las versiones recientes de XEmacs le pregunten si desea moverlo .emacs
a la ubicación exclusiva de XEmacs.
Las diferentes versiones de Emacs pueden tener una expansión diferente e incompatible para algunas macros. Por lo tanto, no comparta sus archivos compilados por bytes entre versiones, compile los archivos en cada máquina.
A veces, una característica está en desuso, pero aún así desea usarla porque eso es todo lo que hay en alguna otra versión que desea admitir. Las advertencias del compilador de bytes provienen de la byte-obsolete-variable
propiedad.
(cond
((not (boundp 'desktop-enable))
(defvaralias 'desktop-enable 'desktop-save-mode))
((get 'desktop-enable 'byte-obsolete-variable)
(put 'desktop-enable 'byte-obsolete-variable nil)))
Speaking Relativamente hablando, en comparación con XEmacs anteriores.
window-system
, etc., se pueden responder razonablemente aquí.