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 setq
para 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 foo
no se establece hasta que utilizo setq
? ¿Y mientras no lo use setq
, puedo usarlo let
para cambiar el valor predeterminado en otros búferes?
EDITAR : como dijo @npostavs, esto es lo que make-varible-buffer-local
realmente significa. Si me uso make-variable-buffer-local
, siempre puedo usar setq
despué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-search
a nil
en 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 setq
antes with-temp-buffer
para asegurarse de que el valor por defecto es en realidad siendo utilizado en caso de que el usuario no tenga eso setq
en su / ella init.el
. Para las variables locales de búfer, probablemente significa setq
que siempre es más seguro que let
cuando 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-buffer
es 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-local
no 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-variable
en su lugar.La segunda cosa a tener en cuenta es la interacción de
let
con 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 siempresetq
inmediatamente despuésmake-variable-buffer-local
?case-fold-search
yfill-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-variable
osetq
mientras 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-variable
cuando veo que la variable ya es "local en el búfer" del manual. Esperaría quelet
pudiera 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-directory
yuniquify-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