diff options
author | Richard M. Stallman <rms@gnu.org> | 1994-03-28 05:41:05 +0000 |
---|---|---|
committer | Richard M. Stallman <rms@gnu.org> | 1994-03-28 05:41:05 +0000 |
commit | 1eecd97285392ffb354bac6cbd1ffe49313edb40 (patch) | |
tree | 9d43b021230854da623f3f04bcb8b0059b69d710 /lispref/positions.texi | |
parent | 479360d34f344d9de840a2f2fb57c8a6ae400055 (diff) | |
download | emacs-1eecd97285392ffb354bac6cbd1ffe49313edb40.tar.gz |
Initial revision
Diffstat (limited to 'lispref/positions.texi')
-rw-r--r-- | lispref/positions.texi | 896 |
1 files changed, 896 insertions, 0 deletions
diff --git a/lispref/positions.texi b/lispref/positions.texi new file mode 100644 index 00000000000..28f52d719bd --- /dev/null +++ b/lispref/positions.texi @@ -0,0 +1,896 @@ +@c -*-texinfo-*- +@c This is part of the GNU Emacs Lisp Reference Manual. +@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +@c See the file elisp.texi for copying conditions. +@setfilename ../info/positions +@node Positions, Markers, Frames, Top +@chapter Positions +@cindex position (in buffer) + + A @dfn{position} is the index of a character in the text of buffer. +More precisely, a position identifies the place between two characters +(or before the first character, or after the last character), so we can +speak of the character before or after a given position. However, the +we often speak of the character ``at'' a position, meaning the character +after that position. + + Positions are usually represented as integers starting from 1, but can +also be represented as @dfn{markers}---special objects which relocate +automatically when text is inserted or deleted so they stay with the +surrounding characters. @xref{Markers}. + +@menu +* Point:: The special position where editing takes place. +* Motion:: Changing point. +* Excursions:: Temporary motion and buffer changes. +* Narrowing:: Restricting editing to a portion of the buffer. +@end menu + +@node Point +@section Point +@cindex point + + @dfn{Point} is a special buffer position used by many editing +commands, including the self-inserting typed characters and text +insertion functions. Other commands move point through the text +to allow editing and insertion at different places. + + Like other positions, point designates a place between two characters +(or before the first character, or after the last character), rather +than a particular character. Many terminals display the cursor over the +character that immediately follows point; on such terminals, point is +actually before the character on which the cursor sits. + +@cindex point with narrowing + The value of point is a number between 1 and the buffer size plus 1. +If narrowing is in effect (@pxref{Narrowing}), then point is constrained +to fall within the accessible portion of the buffer (possibly at one end +of it). + + Each buffer has its own value of point, which is independent of the +value of point in other buffers. Each window also has a value of point, +which is independent of the value of point in other windows on the same +buffer. This is why point can have different values in various windows +that display the same buffer. When a buffer appears in only one window, +the buffer's point and the window's point normally have the same value, +so the distinction is rarely important. @xref{Window Point}, for more +details. + +@defun point +@cindex current buffer position + This function returns the position of point in the current buffer, +as an integer. + +@need 700 +@example +@group +(point) + @result{} 175 +@end group +@end example +@end defun + +@defun point-min + This function returns the minimum accessible value of point in the +current buffer. This is 1, unless narrowing is in effect, in +which case it is the position of the start of the region that you +narrowed to. (@xref{Narrowing}.) +@end defun + +@defun point-max + This function returns the maximum accessible value of point in the +current buffer. This is @code{(1+ (buffer-size))}, unless narrowing is +in effect, in which case it is the position of the end of the region +that you narrowed to. (@xref{Narrowing}). +@end defun + +@defun buffer-end flag + This function returns @code{(point-min)} if @var{flag} is less than 1, +@code{(point-max)} otherwise. The argument @var{flag} must be a number. +@end defun + +@defun buffer-size + This function returns the total number of characters in the current +buffer. In the absence of any narrowing (@pxref{Narrowing}), +@code{point-max} returns a value one larger than this. + +@example +@group +(buffer-size) + @result{} 35 +@end group +@group +(point-max) + @result{} 36 +@end group +@end example +@end defun + +@defvar buffer-saved-size + The value of this buffer-local variable is the former length of the +current buffer, as of the last time it was read in, saved or auto-saved. +@end defvar + +@node Motion +@section Motion + + Motion functions change the value of point, either relative to the +current value of point, relative to the beginning or end of the buffer, +or relative to the edges of the selected window. @xref{Point}. + +@menu +* Character Motion:: Moving in terms of characters. +* Word Motion:: Moving in terms of words. +* Buffer End Motion:: Moving to the beginning or end of the buffer. +* Text Lines:: Moving in terms of lines of text. +* Screen Lines:: Moving in terms of lines as displayed. +* Vertical Motion:: Implementation of @code{next-line} and + @code{previous-line}. +* List Motion:: Moving by parsing lists and sexps. +* Skipping Characters:: Skipping characters belonging to a certain set. +@end menu + +@node Character Motion +@subsection Motion by Characters + + These functions move point based on a count of characters. +@code{goto-char} is the fundamental primitive; the functions others use +that. + +@deffn Command goto-char position +This function sets point in the current buffer to the value +@var{position}. If @var{position} is less than 1, it moves point to the +beginning of the buffer. If @var{position} is greater than the length +of the buffer, it moves point to the end. + +If narrowing is in effect, @var{position} still counts from the +beginning of the buffer, but point cannot go outside the accessible +portion. If @var{position} is out of range, @code{goto-char} moves +point to the beginning or the end of the accessible portion. + +When this function is called interactively, @var{position} is the +numeric prefix argument, if provided; otherwise it is read from the +minibuffer. + +@code{goto-char} returns @var{position}. +@end deffn + +@deffn Command forward-char &optional count +@c @kindex beginning-of-buffer +@c @kindex end-of-buffer +This function moves point @var{count} characters forward, towards the +end of the buffer (or backward, towards the beginning of the buffer, if +@var{count} is negative). If the function attempts to move point past +the beginning or end of the buffer (or the limits of the accessible +portion, when narrowing is in effect), an error is signaled with error +code @code{beginning-of-buffer} or @code{end-of-buffer}. + +In an interactive call, @var{count} is the numeric prefix argument. +@end deffn + +@deffn Command backward-char &optional count +This function moves point @var{count} characters backward, towards the +beginning of the buffer (or forward, towards the end of the buffer, if +@var{count} is negative). If the function attempts to move point past +the beginning or end of the buffer (or the limits of the accessible +portion, when narrowing is in effect), an error is signaled with error +code @code{beginning-of-buffer} or @code{end-of-buffer}. + +In an interactive call, @var{count} is the numeric prefix argument. +@end deffn + +@node Word Motion +@subsection Motion by Words + + These functions for parsing words use the syntax table to decide +whether a given character is part of a word. @xref{Syntax Tables}. + +@deffn Command forward-word count +This function moves point forward @var{count} words (or backward if +@var{count} is negative). Normally it returns @code{t}. If this motion +encounters the beginning or end of the buffer, or the limits of the +accessible portion when narrowing is in effect, point stops there +and the value is @code{nil}. + +In an interactive call, @var{count} is set to the numeric prefix +argument. +@end deffn + +@deffn Command backward-word count +This function just like @code{forward-word}, except that it moves +backward until encountering the front of a word, rather than forward. + +In an interactive call, @var{count} is set to the numeric prefix +argument. + +This function is rarely used in programs, as it is more efficient to +call @code{forward-word} with negative argument. +@end deffn + +@defvar words-include-escapes +@c Emacs 19 feature +This variable affects the behavior of @code{forward-word} and everything +that uses it. If it is non-@code{nil}, then characters in the +``escape'' and ``character quote'' syntax classes count as part of +words. Otherwise, they do not. +@end defvar + +@node Buffer End Motion +@subsection Motion to an End of the Buffer + + To move point to the beginning of the buffer, write: + +@example +@group +(goto-char (point-min)) +@end group +@end example + +@noindent +Likewise, to move to the end of the buffer, use: + +@example +@group +(goto-char (point-max)) +@end group +@end example + + Here are two commands which users use to do these things. They are +documented here to warn you not to use them in Lisp programs, because +they set the mark and display messages in the echo area. + +@deffn Command beginning-of-buffer &optional n +This function moves point to the beginning of the buffer (or the limits +of the accessible portion, when narrowing is in effect), setting the +mark at the previous position. If @var{n} is non-@code{nil}, then it +puts point @var{n} tenths of the way from the beginning of the buffer. + +In an interactive call, @var{n} is the numeric prefix argument, +if provided; otherwise @var{n} defaults to @code{nil}. + +Don't use this function in Lisp programs! +@end deffn + +@deffn Command end-of-buffer &optional n +This function moves point to the end of the buffer (or the limits of +the accessible portion, when narrowing is in effect), setting the mark +at the previous position. If @var{n} is non-@code{nil}, then it puts +point @var{n} tenths of the way from the end. + +In an interactive call, @var{n} is the numeric prefix argument, +if provided; otherwise @var{n} defaults to @code{nil}. + +Don't use this function in Lisp programs! +@end deffn + +@node Text Lines +@subsection Motion by Text Lines +@cindex lines + + Text lines are portions of the buffer delimited by newline characters, +which are regarded as part of the previous line. The first text line +begins at the beginning of the buffer, and the last text line ends at +the end of the buffer whether or not the last character is a newline. +The division of the buffer into text lines is not affected by the width +of the window, by line continuation in display, or by how tabs and +control characters are displayed. + +@deffn Command goto-line line +This function moves point to the front of the @var{line}th line, +counting from line 1 at beginning of buffer. If @var{line} is less than +1, it moves point to the beginning of the buffer. If @var{line} is +greater than the number of lines in the buffer, it moves point to the +@emph{end of the last line} of the buffer. + +If narrowing is in effect, then @var{line} still counts from the +beginning of the buffer, but point cannot go outside the accessible +portion. So @code{goto-line} moves point to the beginning or end of the +accessible portion, if the line number specifies an inaccessible +position. + +The return value of @code{goto-line} is the difference between +@var{line} and the line number of the line to which point actually was +able move (in the full buffer, disregarding any narrowing). Thus, the +value is positive if the scan encounters the real end of the buffer. + +In an interactive call, @var{line} is the numeric prefix argument if +one has been provided. Otherwise @var{line} is read in the minibuffer. +@end deffn + +@deffn Command beginning-of-line &optional count +This function moves point to the beginning of the current line. With an +argument @var{count} not @code{nil} or 1, it moves forward +@var{count}@minus{}1 lines and then to the beginning of the line. + +If this function reaches the end of the buffer (or of the accessible +portion, if narrowing is in effect), it positions point at the end of +the buffer. No error is signaled. +@end deffn + +@deffn Command end-of-line &optional count +This function moves point to the end of the current line. With an +argument @var{count} not @code{nil} or 1, it moves forward +@var{count}@minus{}1 lines and then to the end of the line. + +If this function reaches the end of the buffer (or of the accessible +portion, if narrowing is in effect), it positions point at the end of +the buffer. No error is signaled. +@end deffn + +@deffn Command forward-line &optional count +@cindex beginning of line +This function moves point forward @var{count} lines, to the beginning of +the line. If @var{count} is negative, it moves point +@minus{}@var{count} lines backward, to the beginning of the line. + +If @code{forward-line} encounters the beginning or end of the buffer (or +of the accessible portion) before finding that many lines, it sets point +there. No error is signaled. + +@code{forward-line} returns the difference between @var{count} and the +number of lines actually moved. If you attempt to move down five lines +from the beginning of a buffer that has only three lines, point stops at +the end of the last line, and the value will be 2. + +In an interactive call, @var{count} is the numeric prefix argument. +@end deffn + +@defun count-lines start end +@cindex lines in region +This function returns the number of lines between the positions +@var{start} and @var{end} in the current buffer. If @var{start} and +@var{end} are equal, then it returns 0. Otherwise it returns at least +1, even if @var{start} and @var{end} are on the same line. This is +because the text between them, considered in isolation, must contain at +least one line unless it is empty. + +Here is an example of using @code{count-lines}: + +@example +@group +(defun current-line () + "Return the vertical position of point@dots{}" + (+ (count-lines (window-start) (point)) + (if (= (current-column) 0) 1 0) + -1)) +@end group +@end example +@end defun + +@ignore +@c ================ +The @code{previous-line} and @code{next-line} commands are functions +that should not be used in programs. They are for users and are +mentioned here only for completeness. + +@deffn Command previous-line count +@cindex goal column +This function moves point up @var{count} lines (down if @var{count} +is negative). In moving, it attempts to keep point in the ``goal column'' +(normally the same column that it was at the beginning of the move). + +If there is no character in the target line exactly under the current +column, point is positioned after the character in that line which +spans this column, or at the end of the line if it is not long enough. + +If it attempts to move beyond the top or bottom of the buffer (or clipped +region), then point is positioned in the goal column in the top or +bottom line. No error is signaled. + +In an interactive call, @var{count} will be the numeric +prefix argument. + +The command @code{set-goal-column} can be used to create a semipermanent +goal column to which this command always moves. Then it does not try to +move vertically. + +If you are thinking of using this in a Lisp program, consider using +@code{forward-line} with a negative argument instead. It is usually easier +to use and more reliable (no dependence on goal column, etc.). +@end deffn + +@deffn Command next-line count +This function moves point down @var{count} lines (up if @var{count} +is negative). In moving, it attempts to keep point in the ``goal column'' +(normally the same column that it was at the beginning of the move). + +If there is no character in the target line exactly under the current +column, point is positioned after the character in that line which +spans this column, or at the end of the line if it is not long enough. + +If it attempts to move beyond the top or bottom of the buffer (or clipped +region), then point is positioned in the goal column in the top or +bottom line. No error is signaled. + +In the case where the @var{count} is 1, and point is on the last +line of the buffer (or clipped region), a new empty line is inserted at the +end of the buffer (or clipped region) and point moved there. + +In an interactive call, @var{count} will be the numeric +prefix argument. + +The command @code{set-goal-column} can be used to create a semipermanent +goal column to which this command always moves. Then it does not try to +move vertically. + +If you are thinking of using this in a Lisp program, consider using +@code{forward-line} instead. It is usually easier +to use and more reliable (no dependence on goal column, etc.). +@end deffn + +@c ================ +@end ignore + + Also see the functions @code{bolp} and @code{eolp} in @ref{Near Point}. +These functions do not move point, but test whether it is already at the +beginning or end of a line. + +@node Screen Lines +@subsection Motion by Screen Lines + + The line functions in the previous section count text lines, delimited +only by newline characters. By contrast, these functions count screen +lines, which are defined by the way the text appears on the screen. A +text line is a single screen line if it is short enough to fit the width +of the selected window, but otherwise it may occupy several screen +lines. + + In some cases, text lines are truncated on the screen rather than +continued onto additional screen lines. In these cases, +@code{vertical-motion} moves point much like @code{forward-line}. +@xref{Truncation}. + + Because the width of a given string depends on the flags which control +the appearance of certain characters, @code{vertical-motion} behaves +differently, for a given piece of text, depending on the buffer it is +in, and even on the selected window (because the width, the truncation +flag, and display table may vary between windows). @xref{Usual +Display}. + +@defun vertical-motion count +This function moves point to the start of the screen line @var{count} +screen lines down from the screen line containing point. If @var{count} +is negative, it moves up instead. + +This function returns the number of lines moved. The value may be less +in absolute value than @var{count} if the beginning or end of the buffer +was reached. +@end defun + +@deffn Command move-to-window-line count +This function moves point with respect to the text currently displayed +in the selected window. It moves point to the beginning of the screen +line @var{count} screen lines from the top of the window. If +@var{count} is negative, that specifies a position +@w{@minus{}@var{count}} lines from the bottom---or else the last line of +the buffer, if the buffer ends above the specified screen position. + +If @var{count} is @code{nil}, then point moves to the beginning of the +line in the middle of the window. If the absolute value of @var{count} +is greater than the size of the window, then point moves to the place +which would appear on that screen line if the window were tall enough. +This will probably cause the next redisplay to scroll to bring that +location onto the screen. + +In an interactive call, @var{count} is the numeric prefix argument. + +The value returned is the window line number, with the top line in the +window numbered 0. +@end deffn + +@defun compute-motion from frompos to topos width offsets +This function scan through the current buffer, calculating screen +position. It scans the current buffer forward from position @var{from}, +assuming that is at screen coordinates @var{frompos}, to position +@var{to} or coordinates @var{topos}, whichever comes first. It returns +the ending buffer position and screen coordinates. + +The coordinate arguments @var{frompos} and @var{topos} are cons cells of +the form @code{(@var{hpos} . @var{vpos})}. + +The argument @var{width} is the number of columns available to display +text; this affects handling of continuation lines. Use the value +returned by @code{window-width} for the window of your choice. + +The argument @var{offsets} is either @code{nil} or a cons cell of the +form @code{(@var{hscroll} . @var{tab-offset})}. Here @var{hscroll} is +the number of columns not being displayed at the left margin; in most +calls, this comes from @code{window-hscroll}. Meanwhile, +@var{tab-offset} is the number of columns of an initial tab character +(at @var{from}) that aren't included in the display, perhaps because the +line was continued within that character. + +The return value is a list of five elements: + +@example +(@var{pos} @var{vpos} @var{hpos} @var{prevhpos} @var{contin}) +@end example + +@noindent +Here @var{pos} is the buffer position where the scan stopped, @var{vpos} +is the vertical position, and @var{hpos} is the horizontal position. + +The result @var{prevhpos} is the horizontal position one character back +from @var{pos}. The result @var{contin} is @code{t} if a line was +continued after (or within) the previous character. + +For example, to find the buffer position of column @var{col} of line +@var{line} of a certain window, pass the window's display start location +as @var{from} and the window's upper-left coordinates as @var{frompos}. +Pass the buffer's @code{(point-max)} as @var{to}, to limit the scan to +the end of the visible section of the buffer, and pass @var{line} and +@var{col} as @var{topos}. Here's a function that does this: + +@example +(defun coordinates-of-position (col line) + (car (compute-motion (window-start) + '(0 . 0) + (point) + (cons col line) + (window-width) + (cons (window-hscroll) 0)))) +@end example +@end defun + +@node Vertical Motion +@comment node-name, next, previous, up +@subsection The User-Level Vertical Motion Commands +@cindex goal column +@cindex vertical text line motion +@findex next-line +@findex previous-line + + A goal column is useful if you want to edit text such as a table in +which you want to move point to a certain column on each line. The goal +column affects the vertical text line motion commands, @code{next-line} +and @code{previous-line}. @xref{Basic,, Basic Editing Commands, emacs, +The GNU Emacs Manual}. + +@defopt goal-column +This variable holds an explicitly specified goal column for vertical +line motion commands. If it is an integer, it specifies a column, and +these commands try to move to that column on each line. If it is +@code{nil}, then the commands set their own goal columns. Any other +value is invalid. +@end defopt + +@defvar temporary-goal-column +This variable holds the temporary goal column during a sequence of +consecutive vertical line motion commands. It is overridden by +@code{goal-column} if that is non-@code{nil}. It is set each time a +vertical motion command is invoked, unless the previous command was also +a vertical motion command. +@end defvar + +@defopt track-eol +This variable controls how the vertical line motion commands operate +when starting at the end of a line. If @code{track-eol} is +non-@code{nil}, then vertical motion starting at the end of a line will +keep to the ends of lines. This means moving to the end of each line +moved onto. The value of @code{track-eol} has no effect if point is not +at the end of a line when the first vertical motion command is given. + +@code{track-eol} has its effect by telling line motion commands to set +@code{temporary-goal-column} to 9999 instead of to the current column. +@end defopt + +@node List Motion +@comment node-name, next, previous, up +@subsection Moving over Balanced Expressions +@cindex sexp motion +@cindex Lisp expression motion +@cindex list motion + + Here are several functions concerned with balanced-parenthesis +expressions (also called @dfn{sexps} in connection with moving across +them in Emacs). The syntax table controls how these functions interpret +various characters; see @ref{Syntax Tables}. @xref{Parsing +Expressions}, for lower-level primitives for scanning sexps or parts of +sexps. For user-level commands, see @ref{Lists and Sexps,,, emacs, GNU +Emacs Manual}. + +@deffn Command forward-list arg +Move forward across @var{arg} balanced groups of parentheses. +(Other syntactic entities such as words or paired string quotes +are ignored.) +@end deffn + +@deffn Command backward-list arg +Move backward across @var{arg} balanced groups of parentheses. +(Other syntactic entities such as words or paired string quotes +are ignored.) +@end deffn + +@deffn Command up-list arg +Move forward out of @var{arg} levels of parentheses. +A negative argument means move backward but still to a less deep spot. +@end deffn + +@deffn Command down-list arg +Move forward down @var{arg} levels of parentheses. A negative argument +means move backward but still go down @var{arg} levels. +@end deffn + +@deffn Command forward-sexp arg +Move forward across @var{arg} balanced expressions. +Balanced expressions include both those delimited by parentheses +and other kinds, such as words and string constants. For example, + +@example +@group +---------- Buffer: foo ---------- +(concat@point{} "foo " (car x) y z) +---------- Buffer: foo ---------- +@end group + +@group +(forward-sexp 3) + @result{} nil + +---------- Buffer: foo ---------- +(concat "foo " (car x) y@point{} z) +---------- Buffer: foo ---------- +@end group +@end example +@end deffn + +@deffn Command backward-sexp arg +Move backward across @var{arg} balanced expressions. +@end deffn + +@node Skipping Characters +@comment node-name, next, previous, up +@subsection Skipping Characters +@cindex skipping characters + + The following two functions move point over a specified set of +characters. For example, they are often used to skip whitespace. For +related functions, see @ref{Motion and Syntax}. + +@defun skip-chars-forward character-set &optional limit +This function moves point in the current buffer forward, skipping over a +given set of characters. It examines the character following point, +then advances point if the character matches @var{character-set}. This +continues until it reaches a character that does not match. The +function returns @code{nil}. + +The argument @var{character-set} is like the inside of a +@samp{[@dots{}]} in a regular expression except that @samp{]} is never +special and @samp{\} quotes @samp{^}, @samp{-} or @samp{\}. Thus, +@code{"a-zA-Z"} skips over all letters, stopping before the first +nonletter, and @code{"^a-zA-Z}" skips nonletters stopping before the +first letter. @xref{Regular Expressions}. + +If @var{limit} is supplied (it must be a number or a marker), it +specifies the maximum position in the buffer that point can be skipped +to. Point will stop at or before @var{limit}. + +In the following example, point is initially located directly before the +@samp{T}. After the form is evaluated, point is located at the end of +that line (between the @samp{t} of @samp{hat} and the newline). The +function skips all letters and spaces, but not newlines. + +@example +@group +---------- Buffer: foo ---------- +I read "@point{}The cat in the hat +comes back" twice. +---------- Buffer: foo ---------- +@end group + +@group +(skip-chars-forward "a-zA-Z ") + @result{} nil + +---------- Buffer: foo ---------- +I read "The cat in the hat@point{} +comes back" twice. +---------- Buffer: foo ---------- +@end group +@end example +@end defun + +@defun skip-chars-backward character-set &optional limit +This function moves point backward, skipping characters that match +@var{character-set}, until @var{limit}. It just like +@code{skip-chars-forward} except for the direction of motion. +@end defun + +@node Excursions +@section Excursions +@cindex excursion + + It is often useful to move point ``temporarily'' within a localized +portion of the program, or to switch buffers temporarily. This is +called an @dfn{excursion}, and it is done with the @code{save-excursion} +special form. This construct saves the current buffer and its values of +point and the mark so they can be restored after the completion of the +excursion. + + The forms for saving and restoring the configuration of windows are +described elsewhere (see @ref{Window Configurations}, and @pxref{Frame +Configurations}). + +@defspec save-excursion forms@dots{} +@cindex mark excursion +@cindex point excursion +@cindex current buffer excursion +The @code{save-excursion} special form saves the identity of the current +buffer and the values of point and the mark in it, evaluates @var{forms}, +and finally restores the buffer and its saved values of point and the mark. +All three saved values are restored even in case of an abnormal exit +via throw or error (@pxref{Nonlocal Exits}). + +The @code{save-excursion} special form is the standard way to switch +buffers or move point within one part of a program and avoid affecting +the rest of the program. It is used more than 500 times in the Lisp +sources of Emacs. + +@code{save-excursion} does not save the values of point and the mark for +other buffers, so changes in other buffers remain in effect after +@code{save-excursion} exits. + +@cindex window excursions +Likewise, @code{save-excursion} does not restore window-buffer +correspondences altered by functions such as @code{switch-to-buffer}. +One way to restore these correspondences, and the selected window, is to +use @code{save-window-excursion} inside @code{save-excursion} +(@pxref{Window Configurations}). + +The value returned by @code{save-excursion} is the result of the last of +@var{forms}, or @code{nil} if no @var{forms} are given. + +@example +@group +(save-excursion + @var{forms}) +@equiv{} +(let ((old-buf (current-buffer)) + (old-pnt (point-marker)) + (old-mark (copy-marker (mark-marker)))) + (unwind-protect + (progn @var{forms}) + (set-buffer old-buf) + (goto-char old-pnt) + (set-marker (mark-marker) old-mark))) +@end group +@end example +@end defspec + +@node Narrowing +@section Narrowing +@cindex narrowing +@cindex restriction (in a buffer) +@cindex accessible portion (of a buffer) + + @dfn{Narrowing} means limiting the text addressable by Emacs editing +commands to a limited range of characters in a buffer. The text that +remains addressable is called the @dfn{accessible portion} of the +buffer. + + Narrowing is specified with two buffer positions which become the +beginning and end of the accessible portion. For most editing commands +and most Emacs primitives, these positions replace the values of the +beginning and end of the buffer. While narrowing is in effect, no text +outside the accessible portion is displayed, and point cannot move +outside the accessible portion. + + Values such as positions or line numbers, that usually count from the +beginning of the buffer, do so despite narrowing, but the functions +which use them refuse to operate on text that is inaccessible. + + The commands for saving buffers are unaffected by narrowing; they save +the entire buffer regardless of the any narrowing. + +@deffn Command narrow-to-region start end +This function sets the accessible portion of the current buffer to start +at @var{start} and end at @var{end}. Both arguments should be character +positions. + +In an interactive call, @var{start} and @var{end} are set to the bounds +of the current region (point and the mark, with the smallest first). +@end deffn + +@deffn Command narrow-to-page move-count +This function sets the accessible portion of the current buffer to +include just the current page. An optional first argument +@var{move-count} non-@code{nil} means to move forward or backward by +@var{move-count} pages and then narrow. The variable +@code{page-delimiter} specifies where pages start and end +(@pxref{Standard Regexps}). + +In an interactive call, @var{move-count} is set to the numeric prefix +argument. +@end deffn + +@deffn Command widen +@cindex widening +This function cancels any narrowing in the current buffer, so that the +entire contents are accessible. This is called @dfn{widening}. +It is equivalent to the following expression: + +@example +(narrow-to-region 1 (1+ (buffer-size))) +@end example +@end deffn + +@defspec save-restriction body@dots{} +This special form saves the current bounds of the accessible portion, +evaluates the @var{body} forms, and finally restores the saved bounds, +thus restoring the same state of narrowing (or absence thereof) formerly +in effect. The state of narrowing is restored even in the event of an +abnormal exit via throw or error (@pxref{Nonlocal Exits}). Therefore, +this construct is a clean way to narrow a buffer temporarily. + +The value returned by @code{save-restriction} is that returned by the +last form in @var{body}, or @code{nil} if no body forms were given. + +@c Wordy to avoid overfull hbox. --rjc 16mar92 +@strong{Caution:} it is easy to make a mistake when using the +@code{save-restriction} construct. Read the entire description here +before you try it. + +If @var{body} changes the current buffer, @code{save-restriction} still +restores the restrictions on the original buffer (the buffer whose +restructions it saved from), but it does not restore the identity of the +current buffer. + +@code{save-restriction} does @emph{not} restore point and the mark; use +@code{save-excursion} for that. If you use both @code{save-restriction} +and @code{save-excursion} together, @code{save-excursion} should come +first (on the outside). Otherwise, the old point value would be +restored with temporary narrowing still in effect. If the old point +value were outside the limits of the temporary narrowing, this would +fail to restore it accurately. + +The @code{save-restriction} special form records the values of the +beginning and end of the accessible portion as distances from the +beginning and end of the buffer. In other words, it records the amount +of inaccessible text before and after the accessible portion. + +This method yields correct results if @var{body} does further narrowing. +However, @code{save-restriction} can become confused if the body widens +and then make changes outside the range of the saved narrowing. When +this is what you want to do, @code{save-restriction} is not the right +tool for the job. Here is what you must use instead: + +@example +@group +(let ((beg (point-min-marker)) + (end (point-max-marker))) + (unwind-protect + (progn @var{body}) + (save-excursion + (set-buffer (marker-buffer beg)) + (narrow-to-region beg end)))) +@end group +@end example + +Here is a simple example of correct use of @code{save-restriction}: + +@example +@group +---------- Buffer: foo ---------- +This is the contents of foo +This is the contents of foo +This is the contents of foo@point{} +---------- Buffer: foo ---------- +@end group + +@group +(save-excursion + (save-restriction + (goto-char 1) + (forward-line 2) + (narrow-to-region 1 (point)) + (goto-char (point-min)) + (replace-string "foo" "bar"))) + +---------- Buffer: foo ---------- +This is the contents of bar +This is the contents of bar +This is the contents of foo@point{} +---------- Buffer: foo ---------- +@end group +@end example +@end defspec |