mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-03 10:31:37 -08:00
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.
This commit is contained in:
parent
0fc4761ca8
commit
227213164e
8 changed files with 381 additions and 176 deletions
82
src/buffer.c
82
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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue