summaryrefslogtreecommitdiff
path: root/src/data.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>2000-02-15 09:57:33 +0000
committerRichard M. Stallman <rms@gnu.org>2000-02-15 09:57:33 +0000
commit1f35ce36c2bac1e11b8dea2d6e39a9dccbc2b17b (patch)
tree9abbfd75276782a3dbb14320003f790dffffb2cd /src/data.c
parent6ffd3cf7016259b41cdb14e36780783e88730b48 (diff)
downloademacs-1f35ce36c2bac1e11b8dea2d6e39a9dccbc2b17b.tar.gz
(set_internal): Don't make variable buffer-local
if within a let-binding for the same buffer. (let_shadows_buffer_binding_p): New function.
Diffstat (limited to 'src/data.c')
-rw-r--r--src/data.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/src/data.c b/src/data.c
index eb29de20dbd..669efa5802e 100644
--- a/src/data.c
+++ b/src/data.c
@@ -962,6 +962,23 @@ DEFUN ("set", Fset, Sset, 2, 2, 0,
return set_internal (symbol, newval, current_buffer, 0);
}
+/* Return 1 if SYMBOL currently has a let-binding
+ which was made in the buffer that is now current. */
+
+static int
+let_shadows_buffer_binding_p (symbol)
+ Lisp_Object symbol;
+{
+ struct specbinding *p;
+
+ for (p = specpdl_ptr - 1; p >= specpdl; p--)
+ if (p->func == 0 && CONSP (p->symbol)
+ && XBUFFER (XCDR (XCDR (p->symbol))) == current_buffer)
+ return 1;
+
+ return 0;
+}
+
/* Store the value NEWVAL into SYMBOL.
If buffer-locality is an issue, BUF specifies which buffer to use.
(0 stands for the current buffer.)
@@ -1000,7 +1017,8 @@ set_internal (symbol, newval, buf, bindflag)
register int idx = XBUFFER_OBJFWD (valcontents)->offset;
register int mask = XINT (*((Lisp_Object *)
(idx + (char *)&buffer_local_flags)));
- if (mask > 0 && ! bindflag)
+ if (mask > 0 && ! bindflag
+ && ! let_shadows_buffer_binding_p (symbol))
buf->local_var_flags |= mask;
}
@@ -1068,8 +1086,11 @@ set_internal (symbol, newval, buf, bindflag)
/* If the variable is a Lisp_Some_Buffer_Local_Value,
or if this is `let' rather than `set',
make CURRENT-ALIST-ELEMENT point to itself,
- indicating that we're seeing the default value. */
- if (bindflag || SOME_BUFFER_LOCAL_VALUEP (valcontents))
+ indicating that we're seeing the default value.
+ Likewise if the variable has been let-bound
+ in the current buffer. */
+ if (bindflag || SOME_BUFFER_LOCAL_VALUEP (valcontents)
+ || let_shadows_buffer_binding_p (symbol))
{
XBUFFER_LOCAL_VALUE (valcontents)->found_for_buffer = 0;
@@ -1083,8 +1104,10 @@ set_internal (symbol, newval, buf, bindflag)
tem1 = XBUFFER_LOCAL_VALUE (valcontents)->cdr;
}
/* If it's a Lisp_Buffer_Local_Value, being set not bound,
- give this buffer a new assoc for a local value and set
- CURRENT-ALIST-ELEMENT to point to that. */
+ and we're not within a let that was made for this buffer,
+ create a new buffer-local binding for the variable.
+ That means, give this buffer a new assoc for a local value
+ and set CURRENT-ALIST-ELEMENT to point to that. */
else
{
tem1 = Fcons (symbol, Fcdr (current_alist_element));