changeset 52192:aeb0d981dc7e

(Insertion): Add insert-buffer-substring-no-properties. (Kill Functions): kill-region has new arg yank-handler. (Yanking): New node. (Yank Commands): Add yank-undo-function. (Low-Level Kill Ring): kill-new and kill-append have new arg yank-handler. (Changing Properties): Add remove-list-of-text-properties. (Atomic Changes): New node.
author Richard M. Stallman <rms@gnu.org>
date Wed, 13 Aug 2003 17:28:31 +0000
parents db7b7dd7c12c
children f8d29e8eb4a7
files lispref/text.texi
diffstat 1 files changed, 187 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/lispref/text.texi	Wed Aug 13 17:26:21 2003 +0000
+++ b/lispref/text.texi	Wed Aug 13 17:28:31 2003 +0000
@@ -58,6 +58,7 @@
                        position stored in a register.
 * Base 64::          Conversion to or from base 64 encoding.
 * MD5 Checksum::     Compute the MD5 ``message digest''/``checksum''.
+* Atomic Changes::   Installing several buffer changs ``atomically''.
 * Change Hooks::     Supplying functions to be run when text is changed.
 @end menu
 
@@ -398,6 +399,11 @@
 @end example
 @end defun
 
+@defun insert-buffer-substring-no-properties from-buffer-or-name &optional start end
+This is like @code{insert-buffer-substring} except that it does not
+copy any text properties.
+@end defun
+
   @xref{Sticky Properties}, for other insertion functions that inherit
 text properties from the nearby text in addition to inserting it.
 Whitespace inserted by indentation functions also inherits text
@@ -761,6 +767,7 @@
 @menu
 * Kill Ring Concepts::     What text looks like in the kill ring.
 * Kill Functions::         Functions that kill text.
+* Yanking::                How yanking is done.
 * Yank Commands::          Commands that access the kill ring.
 * Low-Level Kill Ring::	   Functions and variables for kill ring access.
 * Internals of Kill Ring:: Variables that hold kill-ring data.
@@ -805,7 +812,7 @@
 @code{last-command}) whether the previous command was a kill command,
 and if so appends the killed text to the most recent entry.
 
-@deffn Command kill-region start end
+@deffn Command kill-region start end &optional yank-handler
 This function kills the text in the region defined by @var{start} and
 @var{end}.  The text is deleted but saved in the kill ring, along with
 its text properties.  The value is always @code{nil}.
@@ -818,6 +825,10 @@
 ring just the same, then signals an error without modifying the buffer.
 This is convenient because it lets the user use a series of kill
 commands to copy text from a read-only buffer into the kill ring.
+
+If @var{yank-handler} is non-@code{nil}, this puts that value onto
+the string of killed text, as a @code{yank-handler} property.
+@xref{Yanking}.
 @end deffn
 
 @defopt kill-read-only-ok
@@ -842,6 +853,67 @@
 Ring}.
 @end deffn
 
+@node Yanking
+@subsection Yanking
+
+  Yanking means inserting text from the kill ring, but it does
+not insert the text blindly.  Yank commands and some other commands
+use @code{insert-for-yank} to perform special processing on the
+text that they copy into the buffer.
+
+@defun insert-for-yank string
+This function normally works like @code{insert} except that it doesn't
+insert the text properties in the @code{yank-excluded-properties}
+list.  However, if the first character of @var{string} has a
+non-@code{nil}@code{yank-handler} text property, that property
+can do various special processing on the text being inserted.
+@end defun
+
+@defun insert-buffer-substring-as-yank buf &optional start end
+This function resembles @code{insert-buffer-substring} except that it
+doesn't insert the text properties in the
+@code{yank-excluded-properties} list.
+@end defun
+
+  You can put a @code{yank-handler} text property on the text to
+control how it will be inserted if it is yanked.  The
+@code{insert-for-yank} function looks for a @code{yank-handler}
+property on the first character in its @var{string} argument.  The
+property value must be a list of one to four elements, with the
+following format (where elements after the first may be omitted):
+
+@example
+(@var{function} @var{param} @var{noexclude} @var{undo})
+@end example
+
+  Here is what the elements do:
+
+@table @var
+@item function
+When @var{function} is present and non-nil, it is called instead of
+@code{insert} to insert the string.  @var{function} takes one
+argument---the string to insert.
+
+@item param
+If @var{param} is present and non-@code{nil}, it replaces @var{string}
+as the object passed to @var{function} (or @code{insert}); for
+example, if @var{function} is @code{yank-rectangle}, @var{param}
+should be a list of strings to insert as a rectangle.
+
+@item noexclude
+If @var{noexclude} is present and non-@code{nil}, the normal removal of the
+yank-excluded-properties is not performed; instead @var{function} is
+responsible for removing those properties.  This may be necessary
+if @var{function} adjusts point before or after inserting the object.
+
+@item undo
+If @var{undo} is present and non-nil, it is a function that will be
+called by @code{yank-pop} to undo the insertion of the current object.
+It is called with two arguments, the start and end of the current
+region.  @var{function} can set @code{yank-undo-function} to override
+the @var{undo} value.
+@end table
+
 @node Yank Commands
 @comment  node-name,  next,  previous,  up
 @subsection Functions for Yanking
@@ -889,6 +961,17 @@
 The return value is always @code{nil}.
 @end deffn
 
+@defvar yank-undo-function
+If this variable is non-@code{nil}, the function @code{yank-pop} uses
+its value instead of @code{delete-region} to delete the text
+inserted by the previous @code{yank} or
+@code{yank-pop} command.
+
+The function @code{insert-for-yank} automatically sets this variable
+according to the @var{undo} element of the @code{yank-handler}
+text property, if there is one.
+@end defvar
+
 @node Low-Level Kill Ring
 @subsection Low-Level Kill Ring
 
@@ -912,19 +995,23 @@
 the kill ring.
 @end defun
 
-@defun kill-new string
+@defun kill-new string &optional yank-handler
 This function puts the text @var{string} into the kill ring as a new
 entry at the front of the ring.  It discards the oldest entry if
 appropriate.  It also invokes the value of
 @code{interprogram-cut-function} (see below).
+
+If @var{yank-handler} is non-@code{nil}, this puts that value onto
+the string of killed text, as a @code{yank-handler} property.
+@xref{Yanking}.
 @end defun
 
-@defun kill-append string before-p
+@defun kill-append string before-p &optional yank-handler
 This function appends the text @var{string} to the first entry in the
 kill ring.  Normally @var{string} goes at the end of the entry, but if
 @var{before-p} is non-@code{nil}, it goes at the beginning.  This
 function also invokes the value of @code{interprogram-cut-function} (see
-below).
+below).  This handles @var{yank-handler} just like @code{kill-new}.
 @end defun
 
 @defvar interprogram-paste-function
@@ -2435,6 +2522,12 @@
 list.
 @end defun
 
+@defun remove-list-of-text-properties start end list-of-properties &optional object
+Like @code{remove-list-properties} except that
+@var{list-of-properties} is a list property names only, not an
+alternating list of property values.
+@end defun
+
 @defun set-text-properties start end props &optional object
 This function completely replaces the text property list for the text
 between @var{start} and @var{end} in the string or buffer @var{object}.
@@ -3697,6 +3790,96 @@
 coding instead.
 @end defun
 
+@node Atomic Changes
+@section Atomic Change Groups
+@cindex atomic changes
+
+  In data base terminology, an @dfn{atomic} change is an indivisible
+change---it can succeed entirely or it can fail entirely, but it
+cannot partly succeed.  A Lisp program can make a series of changes to
+one or several buffers as an @dfn{atomic change group}, meaning that
+either the entire series of changes will be installed in their buffers
+or, in case of an error, none of them will be.
+
+  To do this for one buffer, the one already current, simply write a
+call to @code{atomic-change-group} around the code that makes the
+changes, like this:
+
+@example
+(atomic-change-group
+  (insert foo)
+  (delete-region x y))
+@end example
+
+@noindent
+If an error (or other nonlocal exit) occurs inside the body of
+@code{atomic-change-group}, it unmakes all the changes in that buffer
+that were during the execution of the body.  This kind of change group
+has no effect on any other buffers--any such changes remain.
+
+  If you need something more sophisticated, such as to make changes in
+various buffers constitute one atomic group, you must directly call
+lower-level functions that @code{atomic-change-group} uses.
+
+@defun prepare-change-group &optional buffer
+This function sets up a change group for buffer @var{buffer}, which
+defaults to the current buffer.  It returns a ``handle'' that
+represents the change group.  You must use this handle to activate the
+change group and subsequently to finish it.
+@end defun
+
+  To use the change group, you must @dfn{activate} it.  You must do
+this before making any changes in the text of @var{buffer}.
+
+@defun activate-change-group handle
+This function activates the change group that @var{handle} designates.
+@end defun
+
+  After you activate the change group, any changes you make in that
+buffer become part of it.  Once you have made all the desired changes
+in the buffer, you must @dfn{finish} the change group.  There are two
+ways to do this: you can either accept (and finalize) all the changes,
+or cancel them all.
+
+@defun accept-change-group handle
+This function accepts all the changes in the change group specified by
+@var{handle}, making them final.
+@end defun
+
+@defun cancel-change-group handle
+This function cancels and undoes all the changes in the change group
+specified by @var{handle}.
+@end defun
+
+  Your code should use @code{unwind-protect} to make sure the group is
+always finished.  The call to @code{activate-change-group} should be
+inside the @code{unwind-protect}, in case the user types @kbd{C-g}
+just after it runs.  (This is one reason why
+@code{prepare-change-group} and @code{activate-change-group} are
+separate functions, because normally you would call
+@code{prepare-change-group} before the start of that
+@code{unwind-protect}.)  Once you finish the group, don't use the
+handle again---in particular, don't try to finish the same group
+twice.
+
+  To make a multibuffer change group, call @code{prepare-change-group}
+once for each buffer you want to cover, then use @code{nconc} to
+combine the returned values, like this:
+
+@example
+(nconc (prepare-change-group buffer-1)
+       (prepare-change-group buffer-2))
+@end example
+
+You can then activate the multibuffer change group with a single call
+to @code{activate-change-group}, and finish it with a single call to
+@code{accept-change-group} or @code{cancel-change-group}.
+
+  Nested use of several change groups for the same buffer works as you
+would expect.  Non-nested use of change groups for the same buffer
+will get Emacs confused, so don't let it happen; the first change
+group you start for any given buffer should be the last one finished.
+
 @node Change Hooks
 @section Change Hooks
 @cindex change hooks