[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master 56c8178 6/7: Document watchpoints
From: |
Noam Postavsky |
Subject: |
[Emacs-diffs] master 56c8178 6/7: Document watchpoints |
Date: |
Sat, 3 Dec 2016 01:45:05 +0000 (UTC) |
branch: master
commit 56c817837bff3ffef587a9c80d619b9fe4886159
Author: Noam Postavsky <address@hidden>
Commit: Noam Postavsky <address@hidden>
Document watchpoints
* doc/lispref/debugging.texi (Variable Debugging):
* doc/lispref/variables.texi (Watching Variables): New section.
* etc/NEWS: Add entry for watchpoints
---
doc/lispref/debugging.texi | 31 ++++++++++++++++++++++
doc/lispref/elisp.texi | 2 ++
doc/lispref/variables.texi | 61 ++++++++++++++++++++++++++++++++++++++++++++
etc/NEWS | 5 ++++
src/data.c | 9 +++++++
5 files changed, 108 insertions(+)
diff --git a/doc/lispref/debugging.texi b/doc/lispref/debugging.texi
index 6c0908a..c80b0f9 100644
--- a/doc/lispref/debugging.texi
+++ b/doc/lispref/debugging.texi
@@ -69,6 +69,7 @@ debugger recursively. @xref{Recursive Editing}.
* Error Debugging:: Entering the debugger when an error happens.
* Infinite Loops:: Stopping and debugging a program that doesn't exit.
* Function Debugging:: Entering it when a certain function is called.
+* Variable Debugging:: Entering it when a variable is modified.
* Explicit Debug:: Entering it at a certain point in the program.
* Using Debugger:: What the debugger does; what you see while in it.
* Debugger Commands:: Commands used while in the debugger.
@@ -290,6 +291,36 @@ Calling @code{cancel-debug-on-entry} does nothing to a
function which is
not currently set up to break on entry.
@end deffn
address@hidden Variable Debugging
address@hidden Entering the debugger when a variable is modified
address@hidden variable write debugging
address@hidden debugging changes to variables
+
+Sometimes a problem with a function is due to a wrong setting of a
+variable. Setting up the debugger to trigger whenever the variable is
+changed is a quick way to find the origin of the setting.
+
address@hidden Command debug-on-variable-change variable
+This function arranges for the debugger to be called whenever
address@hidden is modified.
+
+It is implemented using the watchpoint mechanism, so it inherits the
+same characteristics and limitations: all aliases of @var{variable}
+will be watched together, only dynamic variables can be watched, and
+changes to the objects referenced by variables are not detected. For
+details, see @ref{Watching Variables}.
address@hidden deffn
+
address@hidden Command cancel-debug-on-variable-change &optional variable
+This function undoes the effect of @code{debug-on-variable-change} on
address@hidden When called interactively, it prompts for
address@hidden in the minibuffer. If @var{variable} is omitted or
address@hidden, it cancels break-on-change for all variables. Calling
address@hidden does nothing to a variable
+which is not currently set up to break on change.
address@hidden deffn
+
+
@node Explicit Debug
@subsection Explicit Entry to the Debugger
@cindex debugger, explicit entry
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 708bd9c..6983ab7 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -498,6 +498,7 @@ Variables
* Accessing Variables:: Examining values of variables whose names
are known only at run time.
* Setting Variables:: Storing new values in variables.
+* Watching Variables:: Running a function when a variable is changed.
* Variable Scoping:: How Lisp chooses among local and global values.
* Buffer-Local Variables:: Variable values in effect only in one buffer.
* File Local Variables:: Handling local variable lists in files.
@@ -642,6 +643,7 @@ The Lisp Debugger
* Error Debugging:: Entering the debugger when an error happens.
* Infinite Loops:: Stopping and debugging a program that doesn't exit.
* Function Debugging:: Entering it when a certain function is called.
+* Variable Debugging:: Entering it when a variable is modified.
* Explicit Debug:: Entering it at a certain point in the program.
* Using Debugger:: What the debugger does; what you see while in it.
* Debugger Commands:: Commands used while in the debugger.
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index 4f2274f..d777e4d 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -34,6 +34,7 @@ representing the variable.
* Accessing Variables:: Examining values of variables whose names
are known only at run time.
* Setting Variables:: Storing new values in variables.
+* Watching Variables:: Running a function when a variable is changed.
* Variable Scoping:: How Lisp chooses among local and global values.
* Buffer-Local Variables:: Variable values in effect only in one buffer.
* File Local Variables:: Handling local variable lists in files.
@@ -766,6 +767,66 @@ error is signaled.
@end example
@end defun
address@hidden Watching Variables
address@hidden Running a function when a variable is changed.
address@hidden variable watchpoints
address@hidden watchpoints for Lisp variables
+
+It is sometimes useful to take some action when a variable changes its
+value. The watchpoint facility provides the means to do so. Some
+possible uses for this feature include keeping display in sync with
+variable settings, and invoking the debugger to track down unexpected
+changes to variables (@pxref{Variable Debugging}).
+
+The following functions may be used to manipulate and query the watch
+functions for a variable.
+
address@hidden add-variable-watcher symbol watch-function
+This function arranges for @var{watch-function} to be called whenever
address@hidden is modified. Modifications through aliases
+(@pxref{Variable Aliases}) will have the same effect.
+
address@hidden will be called with 4 arguments: (@var{symbol}
address@hidden @var{operation} @var{where}).
+
address@hidden is the variable being changed.
address@hidden is the value it will be changed to.
address@hidden is a symbol representing the kind of change, one of:
+`set', `let', `unlet', `makunbound', and `defvaralias'.
address@hidden is a buffer if the buffer-local value of the variable is
+being changed, nil otherwise.
address@hidden defun
+
address@hidden remove-variable-watch symbol watch-function
+This function removes @var{watch-function} from @var{symbol}'s list of
+watchers.
address@hidden defun
+
address@hidden get-variable-watchers symbol
+This function returns the list of @var{symbol}'s active watcher
+functions.
address@hidden defun
+
address@hidden Limitations
+
+There are a couple of ways in which a variable could be modifed (or at
+least appear to be modified) without triggering a watchpoint.
+
+Since watchpoints are attached to symbols, modification to the
+objects contained within variables (e.g., by a list modification
+function @pxref{Modifying Lists}) is not caught by this mechanism.
+
+Additionally, C code can modify the value of variables directly,
+bypassing the watchpoint mechanism.
+
+A minor limitation of this feature, again because it targets symbols,
+is that only variables of dynamic scope may be watched. This poses
+little difficulty, since modifications to lexical variables can be
+discovered easily by inspecting the code within the scope of the
+variable (unlike dynamic variables, which can be modified by any code
+at all, @pxref{Variable Scoping}).
+
+
@node Variable Scoping
@section Scoping Rules for Variable Bindings
@cindex scoping rule
diff --git a/etc/NEWS b/etc/NEWS
index 0d2162c..f7565b0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -716,6 +716,11 @@ consistency with the new functions. For compatibility,
'sxhash'
remains as an alias to 'sxhash-equal'.
+++
+** New function `add-variable-watcher' can be used to call a function
+when a symbol's value is changed. This is used to implement the new
+debugger command `debug-on-variable-change'.
+
++++
** Time conversion functions that accept a time zone rule argument now
allow it to be OFFSET or a list (OFFSET ABBR), where the integer
OFFSET is a count of seconds east of Universal Time, and the string
diff --git a/src/data.c b/src/data.c
index 81846b5..eee2a52 100644
--- a/src/data.c
+++ b/src/data.c
@@ -1428,6 +1428,15 @@ harmonize_variable_watchers (Lisp_Object alias,
Lisp_Object base_variable)
DEFUN ("add-variable-watcher", Fadd_variable_watcher, Sadd_variable_watcher,
2, 2, 0,
doc: /* Cause WATCH-FUNCTION to be called when SYMBOL is set.
+
+It will be called with 4 arguments: (SYMBOL NEWVAL OPERATION WHERE).
+SYMBOL is the variable being changed.
+NEWVAL is the value it will be changed to.
+OPERATION is a symbol representing the kind of change, one of: `set',
+`let', `unlet', `makunbound', and `defvaralias'.
+WHERE is a buffer if the buffer-local value of the variable being
+changed, nil otherwise.
+
All writes to aliases of SYMBOL will call WATCH-FUNCTION too. */)
(Lisp_Object symbol, Lisp_Object watch_function)
{
- [Emacs-diffs] master updated (0fc4761 -> 88fefc3), Noam Postavsky, 2016/12/02
- [Emacs-diffs] master 459a234 2/7: Show watchpoints when describing variables, Noam Postavsky, 2016/12/02
- [Emacs-diffs] master cfd2b9e 3/7: Add function to trigger debugger on variable write, Noam Postavsky, 2016/12/02
- [Emacs-diffs] master d3faef9 4/7: Ensure redisplay using variable watcher, Noam Postavsky, 2016/12/02
- [Emacs-diffs] master e7cd98b 5/7: Add tests for watchpoints, Noam Postavsky, 2016/12/02
- [Emacs-diffs] master 56c8178 6/7: Document watchpoints,
Noam Postavsky <=
- [Emacs-diffs] master 2272131 1/7: Add lisp watchpoints, Noam Postavsky, 2016/12/02
- [Emacs-diffs] master 88fefc3 7/7: ; Merge: Lisp watchpoints (Bug#24923), Noam Postavsky, 2016/12/02