aboutsummaryrefslogtreecommitdiffstats
path: root/src/buffer.c
diff options
context:
space:
mode:
authorNoam Postavsky2015-11-19 19:50:06 -0500
committerNoam Postavsky2016-12-02 20:25:14 -0500
commit227213164e06363f0a4fb2beeeb647c99749299e (patch)
tree8fda48112af0631ce9b6c595e33101a9b5961909 /src/buffer.c
parent0fc4761ca88175c30da7209c9ab1cde788b66a76 (diff)
downloademacs-227213164e06363f0a4fb2beeeb647c99749299e.tar.gz
emacs-227213164e06363f0a4fb2beeeb647c99749299e.zip
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)
984 bset_local_var_alist (b, Qnil); 984 bset_local_var_alist (b, Qnil);
985 else 985 else
986 { 986 {
987 Lisp_Object tmp, prop, last = Qnil; 987 Lisp_Object tmp, last = Qnil;
988 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp)) 988 for (tmp = BVAR (b, local_var_alist); CONSP (tmp); tmp = XCDR (tmp))
989 if (!NILP (prop = Fget (XCAR (XCAR (tmp)), Qpermanent_local))) 989 {
990 { 990 Lisp_Object local_var = XCAR (XCAR (tmp));
991 /* If permanent-local, keep it. */ 991 Lisp_Object prop = Fget (local_var, Qpermanent_local);
992 last = tmp; 992
993 if (EQ (prop, Qpermanent_local_hook)) 993 if (!NILP (prop))
994 { 994 {
995 /* This is a partially permanent hook variable. 995 /* If permanent-local, keep it. */
996 Preserve only the elements that want to be preserved. */ 996 last = tmp;
997 Lisp_Object list, newlist; 997 if (EQ (prop, Qpermanent_local_hook))
998 list = XCDR (XCAR (tmp)); 998 {
999 if (!CONSP (list)) 999 /* This is a partially permanent hook variable.
1000 newlist = list; 1000 Preserve only the elements that want to be preserved. */
1001 else 1001 Lisp_Object list, newlist;
1002 for (newlist = Qnil; CONSP (list); list = XCDR (list)) 1002 list = XCDR (XCAR (tmp));
1003 { 1003 if (!CONSP (list))
1004 Lisp_Object elt = XCAR (list); 1004 newlist = list;
1005 /* Preserve element ELT if it's t, 1005 else
1006 if it is a function with a `permanent-local-hook' property, 1006 for (newlist = Qnil; CONSP (list); list = XCDR (list))
1007 or if it's not a symbol. */ 1007 {
1008 if (! SYMBOLP (elt) 1008 Lisp_Object elt = XCAR (list);
1009 || EQ (elt, Qt) 1009 /* Preserve element ELT if it's t,
1010 || !NILP (Fget (elt, Qpermanent_local_hook))) 1010 if it is a function with a `permanent-local-hook' property,
1011 newlist = Fcons (elt, newlist); 1011 or if it's not a symbol. */
1012 } 1012 if (! SYMBOLP (elt)
1013 XSETCDR (XCAR (tmp), Fnreverse (newlist)); 1013 || EQ (elt, Qt)
1014 } 1014 || !NILP (Fget (elt, Qpermanent_local_hook)))
1015 } 1015 newlist = Fcons (elt, newlist);
1016 /* Delete this local variable. */ 1016 }
1017 else if (NILP (last)) 1017 newlist = Fnreverse (newlist);
1018 bset_local_var_alist (b, XCDR (tmp)); 1018 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE)
1019 else 1019 notify_variable_watchers (local_var, newlist,
1020 XSETCDR (last, XCDR (tmp)); 1020 Qmakunbound, Fcurrent_buffer ());
1021 XSETCDR (XCAR (tmp), newlist);
1022 continue; /* Don't do variable write trapping twice. */
1023 }
1024 }
1025 /* Delete this local variable. */
1026 else if (NILP (last))
1027 bset_local_var_alist (b, XCDR (tmp));
1028 else
1029 XSETCDR (last, XCDR (tmp));
1030
1031 if (XSYMBOL (local_var)->trapped_write == SYMBOL_TRAPPED_WRITE)
1032 notify_variable_watchers (local_var, Qnil,
1033 Qmakunbound, Fcurrent_buffer ());
1034 }
1021 } 1035 }
1022 1036
1023 for (i = 0; i < last_per_buffer_idx; ++i) 1037 for (i = 0; i < last_per_buffer_idx; ++i)
@@ -5541,7 +5555,7 @@ file I/O and the behavior of various editing commands.
5541This variable is buffer-local but you cannot set it directly; 5555This variable is buffer-local but you cannot set it directly;
5542use the function `set-buffer-multibyte' to change a buffer's representation. 5556use the function `set-buffer-multibyte' to change a buffer's representation.
5543See also Info node `(elisp)Text Representations'. */); 5557See also Info node `(elisp)Text Representations'. */);
5544 XSYMBOL (intern_c_string ("enable-multibyte-characters"))->constant = 1; 5558 make_symbol_constant (intern_c_string ("enable-multibyte-characters"));
5545 5559
5546 DEFVAR_PER_BUFFER ("buffer-file-coding-system", 5560 DEFVAR_PER_BUFFER ("buffer-file-coding-system",
5547 &BVAR (current_buffer, buffer_file_coding_system), Qnil, 5561 &BVAR (current_buffer, buffer_file_coding_system), Qnil,