Digamos que defino una variable local de búfer foo, y su valor predeterminado es "a":
(defvar foo "a")
(make-variable-buffer-local 'foo)
(default-value 'foo) ;; => "a"
Inmediatamente después de esto ejecuto el siguiente código:
(let ((foo "b"))
(with-temp-buffer
(message "foo: %s" foo))) ;; => "b"
El resultado es "b", que es el valor que establecí let.
Ahora, si uso setqpara configurar la variable, vuelva a ejecutar exactamente el mismo código que antes:
(setq foo "c") ;; => "c"
(let ((foo "b"))
(with-temp-buffer
(message "foo: %s" foo))) ;; => "a"
El resultado es "a", que es el valor predeterminado ahora.
La pregunta : por un buffer temporal, el valor por defecto de foono se establece hasta que utilizo setq? ¿Y mientras no lo use setq, puedo usarlo letpara cambiar el valor predeterminado en otros búferes?
EDITAR : como dijo @npostavs, esto es lo que make-varible-buffer-localrealmente significa. Si me uso make-variable-buffer-local, siempre puedo usar setqdespués de eso. Pero esto se vuelve realmente complicado para las variables locales de búfer "incorporadas" como case-fold-search. si yo, como autor del paquete, se unen case-fold-searcha nilen el exterior let, y quiero usar el valor por defecto (que puede o no puede ser establecido por el usuario) en el with-temp-buffer, tengo que usar setqantes with-temp-bufferpara asegurarse de que el valor por defecto es en realidad siendo utilizado en caso de que el usuario no tenga eso setqen su / ella init.el. Para las variables locales de búfer, probablemente significa setqque siempre es más seguro que letcuando queremos establecer el valor. Me pregunto si el diseño o la documentación podrían mejorarse.
fuente

with-temp-buffer(en lugar de antes), ¿eso ayuda?with-temp-bufferes una macro y se comporta de manera un poco diferente a una función estándar. Por ejemplo,(with-temp-buffer (let ((foo "b")) (message "foo: %s" foo)))with-temp-buffer(dicho esto, sin macros). Creo que es más como un comportamiento específico para las variables locales de búfer.Respuestas:
En este caso recomendaría
¡Lo importante a tener en cuenta aquí es que
make-variable-buffer-localno crea una variable local de búfer! Solo se arregla para que se convierta en buffer local después de que se establece . Es posible que desee utilizarmake-local-variableen su lugar.La segunda cosa a tener en cuenta es la interacción de
letcon las variables locales de búfer, de(elisp) Intro to Buffer-Local:Así, en el primer caso que enlaza el valor mundial de
"b"y que se muestra en el buffer temporal. En el segundo caso, después de haber ajustado el valor local en el*scratch*que"c", a continuación, se unen el valor local a"b", pero otros tampones todavía ven el valor global de"a".fuente
Make VARIABLE become buffer-local whenever it is set.. Pensé que estaba diciendo que cada vez que establecemos el valor, solo se establece el valor local del búfer. Entonces, para evitar tal problema, ¿deberíamos usarlo siempresetqinmediatamente despuésmake-variable-buffer-local?case-fold-searchyfill-column. Emacs en sí no los configura después de definir estas variables locales de búfer, y requiere que el usuario las configure para que sean realmente locales de búfer. ¿Es este diseño intencional? No creo que la mayoría de la gente lo sepa.make-local-variableosetqmientras dice que esta variable es un buffer local es realmente confuso. Pero tal vez esa sea otra pregunta con respecto al diseño.make-local-variablecuando veo que la variable ya es "local en el búfer" del manual. Esperaría queletpudiera enlazar la copia local del búfer. Pero esto puede ser más adecuado para preguntar en Emacs-devel.Al igual que su solución propuesta, podemos vincular esto a una variable arbitraria dentro
let, luego cambiarlo como desee mientras permanece dentrolet, antes de volver al valor original.El problema surge cuando se cambia el búfer en el interior
let: debido al alcance dinámico, el valor de las variables locales no se 'transferirá' al nuevo búfer, incluso dentrolexical-let.Aquí hay una función que comprueba este problema y también establece y revierte el valor predeterminado, que es el utilizado por un búfer temporal:
entonces
y "xyz" aparecerá en el
*Messages*búfer.Otras variables locales que vienen a la mente en este contexto son
default-directoryyuniquify-managed...En resumen, podría definir una función como esta y usarla en su interior
let, así que ahorre la molestia de verificar si la variable (símbolo) es local o no:fuente