Mercurial > emacs
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