summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
authorNoam Postavsky <npostavs@gmail.com>2015-11-19 19:50:06 -0500
committerNoam Postavsky <npostavs@gmail.com>2016-12-02 20:25:14 -0500
commit227213164e06363f0a4fb2beeeb647c99749299e (patch)
tree8fda48112af0631ce9b6c595e33101a9b5961909 /src/buffer.c
parent0fc4761ca88175c30da7209c9ab1cde788b66a76 (diff)
Add lisp watchpoints
This allows calling a function whenever a symbol-value is changed. * src/lisp.h (lisp_h_SYMBOL_TRAPPED_WRITE_P): (SYMBOL_TRAPPED_WRITE_P): New function/macro. (lisp_h_SYMBOL_CONSTANT_P): Check for SYMBOL_NOWRITE specifically. (enum symbol_trapped_write): New enumeration. (struct Lisp_Symbol): Rename field constant to trapped_write. (make_symbol_constant): New function. * src/data.c (Fadd_variable_watcher, Fremove_variable_watcher): (set_symbol_trapped_write, restore_symbol_trapped_write): (harmonize_variable_watchers, notify_variable_watchers): New functions. * src/data.c (Fset_default): Call `notify_variable_watchers' for trapped symbols. (set_internal): Change bool argument BIND to 3-value enum and call `notify_variable_watchers' for trapped symbols. * src/data.c (syms_of_data): * src/data.c (syms_of_data): * src/font.c (syms_of_font): * src/lread.c (intern_sym, init_obarray): * src/buffer.c (syms_of_buffer): Use make_symbol_constant. * src/alloc.c (init_symbol): * src/bytecode.c (exec_byte_code): Use SYMBOL_TRAPPED_WRITE_P. * src/data.c (Fmake_variable_buffer_local, Fmake_local_variable): (Fmake_variable_frame_local): * src/eval.c (Fdefvaralias, specbind): Refer to Lisp_Symbol's trapped_write instead of constant. (Ffuncall): Move subr calling code into separate function. (funcall_subr): New function.
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c82
1 files changed, 48 insertions, 34 deletions
diff --git a/src/buffer.c b/src/buffer.c
index aa556b75bc6..6815aa7f7ed 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -984,40 +984,54 @@ reset_buffer_local_variables (struct buffer *b, bool permanent_too)
bset_local_var_alist (b, Qnil);
else
{
- Lisp_Object tmp, prop, last = Qnil;
+ Lisp_Object tmp, last = Qnil;
for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
- if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local)))
- {
- /* If permanent-local, keep it. */
- last = tmp;
- if (EQ (prop, Qpermanent_local_hook))
- {
- /* This is a partially permanent hook variable.
- Preserve only the elements that want to be preserved. */
- Lisp_Object list, newlist;
- list = XCDR (XCAR (tmp));
- if (!CONSP (list))
- newlist = list;
- else
- for (newlist = Qnil; CONSP (list); list = XCDR (list))
- {
- Lisp_Object elt = XCAR (list);
- /* Preserve element ELT if it's t,
- if it is a function with a `permanent-local-hook' property,
- or if it's not a symbol. */
- if (! SYMBOLP (elt)
- || EQ (elt, Qt)
- || !NILP (Fget (elt, Qpermanent_local_hook)))
- newlist = Fcons (elt, newlist);
- }
- XSETCDR (XCAR (tmp), Fnreverse (newlist));
- }
- }
- /* Delete this local variable. */
- else if (NILP (last))
- bset_local_var_alist (b, XCDR (tmp));
- else
- XSETCDR (last, XCDR (tmp));
+ {
+ Lisp_Object local_var = XCAR (XCAR (tmp));
+ Lisp_Object prop = Fget (local_var, Qpermanent_local);
+
+ if (!NILP (prop))
+ {
+ /* If permanent-local, keep it. */
+ last = tmp;
+ if (EQ (prop, Qpermanent_local_hook))
+ {
+ /* This is a partially permanent hook variable.
+ Preserve only the elements that want to be preserved. */
+ Lisp_Object list, newlist;
+ list = XCDR (XCAR (tmp));
+ if (!CONSP (list))
+ newlist = list;
+ else
+ for (newlist = Qnil; CONSP (list); list = XCDR (list))
+ {
+ Lisp_Object elt = XCAR (list);
+ /* Preserve element ELT if it's t,
+ if it is a function with a `permanent-local-hook' property,
+ or if it's not a symbol. */
+ if (! SYMBOLP (elt)
+ || EQ (elt, Qt)
+ || !NILP (Fget (elt, Qpermanent_local_hook)))
+ newlist = Fcons (elt, newlist);
+ }
+ newlist = Fnreverse (newlist);
+ if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE)
+ notify_variable_watchers (local_var, newlist,
+ Qmakunbound, Fcurrent_buffer ());
+ XSETCDR (XCAR (tmp), newlist);
+ continue; /* Don't do variable write trapping twice. */
+ }
+ }
+ /* Delete this local variable. */
+ else if (NILP (last))
+ bset_local_var_alist (b, XCDR (tmp));
+ else
+ XSETCDR (last, XCDR (tmp));
+
+ if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE)
+ notify_variable_watchers (local_var, Qnil,
+ Qmakunbound, Fcurrent_buffer ());
+ }
}
for (i = 0; i < last_per_buffer_idx; ++i)
@@ -5541,7 +5555,7 @@ file I/O and the behavior of various editing commands.
This variable is buffer-local but you cannot set it directly;
use the function `set-buffer-multibyte' to change a buffer's representation.
See also Info node `(elisp)Text Representations'. */);
- XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1;
+ make_symbol_constant (intern_c_string ("enable-multibyte-characters"));
DEFVAR_PER_BUFFER ("buffer-file-coding-system",
&BVAR (current_buffer, buffer_file_coding_system), Qnil,