Supongamos que tengo un búfer Emacs lisp que contiene:
(defvar foo 1)
Si llamo eval-last-sexpo eval-buffer, fooestá vinculado a 1. Si luego edito este búfer para:
(defvar foo 2)
eval-last-sexpy eval-bufferno vuelva a ejecutar esta línea, por foolo que sigue siendo 1.
Esto es particularmente desafiante cuando hay múltiples declaraciones de este tipo y tengo que rastrear qué líneas no se están reevaluando.
Miré simplemente reiniciar Emacs y luego (require 'foo), pero luego tengo que tener cuidado para evitar cargar cualquier archivo .elc anterior.
¿Cómo puedo estar absolutamente seguro de que las variables y funciones definidas en el archivo actual están en el mismo estado que el código de carga nuevamente en una nueva instancia de Emacs?
interactive-development
Wilfred Hughes
fuente
fuente

makunboundy luego volver a evaluar el código en el búfer.(incf emacs-major-version)que puedo vivir ocurren repetidamente. Estoy interesado en hackear el código con muchasdefvarformas.Respuestas:
Como se explica en otras respuestas, la evaluación de un
defvarformulario usandoeval-last-sexpno restablece el valor predeterminado.En su lugar, puede utilizar
eval-defun(con destinoC-M-xenemacs-lisp-modeforma predeterminada), que implementa el comportamiento que desea como una excepción especial:Si necesita evaluar el contenido completo de un búfer, puede escribir una función que recorra los formularios de nivel superior y llame
eval-defuna cada uno. Algo como esto debería funcionar:fuente
eval-defunlugar deeval-last-sexp. Incluso puede escribir una función que llameeval-defuna cada formulario en el búfer y usarlo en lugar deeval-buffer.eval-defunlugar deeval-last-sexp, claro, pero la dificultad es paraeval-buffer.eval-defuna cada formulario de nivel superior en el búfer.defvarno está dentro de adefun. Ejemplo:(progn (defvar foo "bar")).defconst(que siempre se reevalúan). Recientemente ha habido una publicación muy esclarecedora sobre este tema entre paréntesis interminablesComo dicen las otras respuestas, esta es la forma en que defvar funciona, pero puedes evitarlo, después de todo, es elisp.
Puede redefinir temporalmente cómo funciona defvar si lo desea y, durante ese tiempo, volver a cargar los paquetes que desea restablecer.
Escribí una macro donde durante la evaluación del cuerpo, los valores de defvars siempre serán reevaluados.
Ejemplo de uso:
file_a.el
file_b.el
Nota: Esto solo debe usarse con el propósito de reevaluar los defvars, ya que simplemente ignora las cadenas de documentos al reevaluar. Puede modificar la macro para admitir la reevaluación que también aplica docstrings, pero se lo dejaré a usted.
En tu caso podrías hacer
Pero sepa lo que hacen los que escriben elisp esperando que defvar funcione como se especifica, podría ser que usan defvar para definir y establecer q en alguna función de inicio para especificar el valor, por lo que puede terminar con variables nulas que no pretende pero Esto es probablemente raro.
Implementación Alternativa
Con esto, puede redefinir defvar globalmente y controlar si establecerá o no el valor del símbolo en el argumento INIT-VALUE incluso si el símbolo se define cambiando el valor del nuevo
defvar-always-reeval-valuessímbolo.fuente
defvares una buena idea: hay varios usos posibles diferentesdefvar, con semánticas ligeramente diferentes. Por ejemplo, un uso que su macro no tiene en cuenta es el(defvar SYMBOL)formulario, que se utiliza para decirle al compilador de bytes sobre la existencia de una variable sin establecer un valor.defvarcon una macro, probablemente sea mejor prefijar eldefvarformulario original con amakunbound, en lugar de reemplazarlo porsetq.Se
defvarestá evaluando y haciendo exactamente lo que ha especificado. Sin embargo,defvarsolo establece un valor inicial:Entonces, para lograr lo que desea, necesitaría desvincular la variable antes de reevaluar, por ejemplo
o use
setqpara establecer el valor, por ej.Si no necesita especificar una cadena de documentación aquí, puede omitirla por
defvarcompleto.Si realmente desea usar
defvary desvincular esto automáticamente, deberá escribir una función para buscardefvarllamadas en el búfer actual (o región, o el último sexp, etc.); llamamakunbounda cada uno; y luego hacer la evaluación real.fuente
eval-bufferenvoltura que desenredaría todo primero, pero la respuesta de @ Francescoeval-defunes realmente lo que quieres.La siguiente macro se creó rastreando
eval-defunsus funciones de soporte y modificándola para que ya no sea necesario evaluar una región de un búfer particular. Necesitaba ayuda en el hilo relacionado Convirtiendo una expresión en una cadena , y @Tobias acudió al rescate, enseñándome cómo convertir la función imperfecta en una macro. No creo que tengamoseval-sexp-add-defvarsque precederelisp--eval-defun-1, pero si alguien piensa que es importante, hágamelo saber.fuente
El problema no es que la línea no se vuelva a evaluar. El problema es que
defvardefine una variable y su valor predeterminado . Si ya existe una variable, cambiar su valor predeterminado no modifica el valor actual. Desafortunadamente, creo que necesitará ejecutar unsetqpara cada variable cuyo valor desea actualizar.Esto puede ser excesivo, pero puede actualizar su archivo de esta manera si desea poder actualizar fácilmente
fooa su nuevo valor predeterminado.pero eso requiere que mantenga el valor predeterminado en dos lugares en su código. También puedes hacer esto:
pero si existe la posibilidad de que
foose declare en otro lugar, puede tener algunos efectos secundarios para tratar.fuente
eval-defuntratadefvarespecialmente, así que seguramente hay algo similar para tampones enteros?makunboundlas variables declaradas en el búfer actual y luego la reevalúe? Podrías escribir el tuyo, pero no creo que haya una función lista para usar para esto. EDITAR: No importa, entiendo lo que estás diciendo. Uneval-defunque funciona en todo el búfer. Parece que @JordonBiondo tiene su solución para eso.defvarno hace nada si la variable ya tiene un valor (como dice su documento:)The optional argument INITVALUE is evaluated, and used to set SYMBOL, only if SYMBOL's value is void.. El problema no es quedefvarcambie el valor predeterminado y no el valor actual.(defvar a 4) (default-value 'a) (setq a 2) (default-value 'a); luegoC-x C-edespués deldefvarsexp; entonces(default-value 'a).C-x C-e,eval-regiony similares en undefvarsexp no cambian el valor predeterminado.