Previous: , Up: Positions   [Contents][Index]


41.4 Narrowing

Narrowing means limiting the text addressable by SXEmacs editing commands to a limited range of characters in a buffer. The text that remains addressable is called the 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 SXEmacs 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, which 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 any narrowing.

Command: narrow-to-region start end &optional buffer

This function sets the accessible portion of buffer to start at start and end at end. Both arguments should be character positions. buffer defaults to the current buffer if omitted.

In an interactive call, start and end are set to the bounds of the current region (point and the mark, with the smallest first).

Command: narrow-to-page &optional move-count

This function sets the accessible portion of the current buffer to include just the current page. An optional first argument move-count non-nil means to move forward or backward by move-count pages and then narrow. The variable page-delimiter specifies where pages start and end (see Standard Regexps).

In an interactive call, move-count is set to the numeric prefix argument.

Command: widen &optional buffer

This function cancels any narrowing in buffer, so that the entire contents are accessible. This is called widening. It is equivalent to the following expression:

(narrow-to-region 1 (1+ (buffer-size)))

buffer defaults to the current buffer if omitted.

Special Form: save-restriction body…

This special form saves the current bounds of the accessible portion, evaluates the 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 (see Nonlocal Exits). Therefore, this construct is a clean way to narrow a buffer temporarily.

The value returned by save-restriction is that returned by the last form in body, or nil if no body forms were given.

Caution: it is easy to make a mistake when using the save-restriction construct. Read the entire description here before you try it.

If body changes the current buffer, save-restriction still restores the restrictions on the original buffer (the buffer whose restrictions it saved from), but it does not restore the identity of the current buffer.

save-restriction does not restore point and the mark; use save-excursion for that. If you use both save-restriction and save-excursion together, 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 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 body does further narrowing. However, 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, save-restriction is not the right tool for the job. Here is what you must use instead:

(let ((start (point-min-marker))
      (end (point-max-marker)))
  (unwind-protect
      (progn body)
    (save-excursion
      (set-buffer (marker-buffer start))
      (narrow-to-region start end))))

Here is a simple example of correct use of save-restriction:

---------- Buffer: foo ----------
This is the contents of foo
This is the contents of foo
This is the contents of foo∗
---------- Buffer: foo ----------
(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∗
---------- Buffer: foo ----------

Previous: , Up: Positions   [Contents][Index]