elisp: Current Buffer

 
 26.2 The Current Buffer
 =======================
 
 There are, in general, many buffers in an Emacs session.  At any time,
 one of them is designated the “current buffer”—the buffer in which most
 editing takes place.  Most of the primitives for examining or changing
 text operate implicitly on the current buffer (SeeText).
 
    Normally, the buffer displayed in the selected window is the current
 buffer, but this is not always so: a Lisp program can temporarily
 designate any buffer as current in order to operate on its contents,
 without changing what is displayed on the screen.  The most basic
 function for designating a current buffer is ‘set-buffer’.
 
  -- Function: current-buffer
      This function returns the current buffer.
 
           (current-buffer)
                ⇒ #<buffer buffers.texi>
 
  -- Function: set-buffer buffer-or-name
      This function makes BUFFER-OR-NAME the current buffer.
      BUFFER-OR-NAME must be an existing buffer or the name of an
      existing buffer.  The return value is the buffer made current.
 
      This function does not display the buffer in any window, so the
      user cannot necessarily see the buffer.  But Lisp programs will now
      operate on it.
 
    When an editing command returns to the editor command loop, Emacs
 automatically calls ‘set-buffer’ on the buffer shown in the selected
 window.  This is to prevent confusion: it ensures that the buffer that
 the cursor is in, when Emacs reads a command, is the buffer to which
 that command applies (SeeCommand Loop).  Thus, you should not use
 ‘set-buffer’ to switch visibly to a different buffer; for that, use the
 functions described in SeeSwitching Buffers.
 
    When writing a Lisp function, do _not_ rely on this behavior of the
 command loop to restore the current buffer after an operation.  Editing
 commands can also be called as Lisp functions by other programs, not
 just from the command loop; it is convenient for the caller if the
 subroutine does not change which buffer is current (unless, of course,
 that is the subroutine’s purpose).
 
    To operate temporarily on another buffer, put the ‘set-buffer’ within
 a ‘save-current-buffer’ form.  Here, as an example, is a simplified
 version of the command ‘append-to-buffer’:
 
      (defun append-to-buffer (buffer start end)
        "Append the text of the region to BUFFER."
        (interactive "BAppend to buffer: \nr")
        (let ((oldbuf (current-buffer)))
          (save-current-buffer
            (set-buffer (get-buffer-create buffer))
            (insert-buffer-substring oldbuf start end))))
 
 Here, we bind a local variable to record the current buffer, and then
 ‘save-current-buffer’ arranges to make it current again later.  Next,
 ‘set-buffer’ makes the specified buffer current, and
 ‘insert-buffer-substring’ copies the string from the original buffer to
 the specified (and now current) buffer.
 
    Alternatively, we can use the ‘with-current-buffer’ macro:
 
      (defun append-to-buffer (buffer start end)
        "Append the text of the region to BUFFER."
        (interactive "BAppend to buffer: \nr")
        (let ((oldbuf (current-buffer)))
          (with-current-buffer (get-buffer-create buffer)
            (insert-buffer-substring oldbuf start end))))
 
    In either case, if the buffer appended to happens to be displayed in
 some window, the next redisplay will show how its text has changed.  If
 it is not displayed in any window, you will not see the change
 immediately on the screen.  The command causes the buffer to become
 current temporarily, but does not cause it to be displayed.
 
    If you make local bindings (with ‘let’ or function arguments) for a
 variable that may also have buffer-local bindings, make sure that the
 same buffer is current at the beginning and at the end of the local
 binding’s scope.  Otherwise you might bind it in one buffer and unbind
 it in another!
 
    Do not rely on using ‘set-buffer’ to change the current buffer back,
 because that won’t do the job if a quit happens while the wrong buffer
 is current.  For instance, in the previous example, it would have been
 wrong to do this:
 
        (let ((oldbuf (current-buffer)))
          (set-buffer (get-buffer-create buffer))
          (insert-buffer-substring oldbuf start end)
          (set-buffer oldbuf))
 
 Using ‘save-current-buffer’ or ‘with-current-buffer’, as we did,
 correctly handles quitting, errors, and ‘throw’, as well as ordinary
 evaluation.
 
  -- Special Form: save-current-buffer body...
      The ‘save-current-buffer’ special form saves the identity of the
      current buffer, evaluates the BODY forms, and finally restores that
      buffer as current.  The return value is the value of the last form
      in BODY.  The current buffer is restored even in case of an
      abnormal exit via ‘throw’ or error (SeeNonlocal Exits).
 
      If the buffer that used to be current has been killed by the time
      of exit from ‘save-current-buffer’, then it is not made current
      again, of course.  Instead, whichever buffer was current just
      before exit remains current.
 
  -- Macro: with-current-buffer buffer-or-name body...
      The ‘with-current-buffer’ macro saves the identity of the current
      buffer, makes BUFFER-OR-NAME current, evaluates the BODY forms, and
      finally restores the current buffer.  BUFFER-OR-NAME must specify
      an existing buffer or the name of an existing buffer.
 
      The return value is the value of the last form in BODY.  The
      current buffer is restored even in case of an abnormal exit via
      ‘throw’ or error (SeeNonlocal Exits).
 
  -- Macro: with-temp-buffer body...
      The ‘with-temp-buffer’ macro evaluates the BODY forms with a
      temporary buffer as the current buffer.  It saves the identity of
      the current buffer, creates a temporary buffer and makes it
      current, evaluates the BODY forms, and finally restores the
      previous current buffer while killing the temporary buffer.  By
      default, undo information (SeeUndo) is not recorded in the
      buffer created by this macro (but BODY can enable that, if needed).
 
      The return value is the value of the last form in BODY.  You can
      return the contents of the temporary buffer by using
      ‘(buffer-string)’ as the last form.
 
      The current buffer is restored even in case of an abnormal exit via
      ‘throw’ or error (SeeNonlocal Exits).
 
      See also ‘with-temp-file’ in SeeWriting to Files Definition of
      with-temp-file.