elisp: Undo

 
 31.9 Undo
 =========
 
 Most buffers have an “undo list”, which records all changes made to the
 buffer’s text so that they can be undone.  (The buffers that don’t have
 one are usually special-purpose buffers for which Emacs assumes that
 undoing is not useful.  In particular, any buffer whose name begins with
 a space has its undo recording off by default; see SeeBuffer
 Names.)  All the primitives that modify the text in the buffer
 automatically add elements to the front of the undo list, which is in
 the variable ‘buffer-undo-list’.
 
  -- Variable: buffer-undo-list
      This buffer-local variable’s value is the undo list of the current
      buffer.  A value of ‘t’ disables the recording of undo information.
 
    Here are the kinds of elements an undo list can have:
 
 ‘POSITION’
      This kind of element records a previous value of point; undoing
      this element moves point to POSITION.  Ordinary cursor motion does
      not make any sort of undo record, but deletion operations use these
      entries to record where point was before the command.
 
 ‘(BEG . END)’
      This kind of element indicates how to delete text that was
      inserted.  Upon insertion, the text occupied the range BEG–END in
      the buffer.
 
 ‘(TEXT . POSITION)’
      This kind of element indicates how to reinsert text that was
      deleted.  The deleted text itself is the string TEXT.  The place to
      reinsert it is ‘(abs POSITION)’.  If POSITION is positive, point
      was at the beginning of the deleted text, otherwise it was at the
      end.  Zero or more (MARKER .  ADJUSTMENT) elements follow
      immediately after this element.
 
 ‘(t . TIME-FLAG)’
      This kind of element indicates that an unmodified buffer became
      modified.  A TIME-FLAG of the form ‘(SEC-HIGH SEC-LOW MICROSEC
      PICOSEC)’ represents the visited file’s modification time as of
      when it was previously visited or saved, using the same format as
      ‘current-time’; see SeeTime of Day.  A TIME-FLAG of 0 means
      the buffer does not correspond to any file; −1 means the visited
      file previously did not exist.  ‘primitive-undo’ uses these values
      to determine whether to mark the buffer as unmodified once again;
      it does so only if the file’s status matches that of TIME-FLAG.
 
 ‘(nil PROPERTY VALUE BEG . END)’
      This kind of element records a change in a text property.  Here’s
      how you might undo the change:
 
           (put-text-property BEG END PROPERTY VALUE)
 
 ‘(MARKER . ADJUSTMENT)’
      This kind of element records the fact that the marker MARKER was
      relocated due to deletion of surrounding text, and that it moved
      ADJUSTMENT character positions.  If the marker’s location is
      consistent with the (TEXT .  POSITION) element preceding it in the
      undo list, then undoing this element moves MARKER − ADJUSTMENT
      characters.
 
 ‘(apply FUNNAME . ARGS)’
      This is an extensible undo item, which is undone by calling FUNNAME
      with arguments ARGS.
 
 ‘(apply DELTA BEG END FUNNAME . ARGS)’
      This is an extensible undo item, which records a change limited to
      the range BEG to END, which increased the size of the buffer by
      DELTA characters.  It is undone by calling FUNNAME with arguments
      ARGS.
 
      This kind of element enables undo limited to a region to determine
      whether the element pertains to that region.
 
 ‘nil’
      This element is a boundary.  The elements between two boundaries
      are called a “change group”; normally, each change group
      corresponds to one keyboard command, and undo commands normally
      undo an entire group as a unit.
 
  -- Function: undo-boundary
      This function places a boundary element in the undo list.  The undo
      command stops at such a boundary, and successive undo commands undo
      to earlier and earlier boundaries.  This function returns ‘nil’.
 
      Calling this function explicitly is useful for splitting the
      effects of a command into more than one unit.  For example,
      ‘query-replace’ calls ‘undo-boundary’ after each replacement, so
      that the user can undo individual replacements one by one.
 
      Mostly, however, this function is called automatically at an
      appropriate time.
 
  -- Function: undo-auto-amalgamate
      The editor command loop automatically calls ‘undo-boundary’ just
      before executing each key sequence, so that each undo normally
      undoes the effects of one command.  A few exceptional commands are
      “amalgamating”: these commands generally cause small changes to
      buffers, so with these a boundary is inserted only every 20th
      command, allowing the changes to be undone as a group.  By default,
      the commands ‘self-insert-command’, which produces self-inserting
      input characters (SeeCommands for Insertion), and
      ‘delete-char’, which deletes characters (SeeDeletion), are
      amalgamating.  Where a command affects the contents of several
      buffers, as may happen, for example, when a function on the
      ‘post-command-hook’ affects a buffer other than the
      ‘current-buffer’, then ‘undo-boundary’ will be called in each of
      the affected buffers.
 
  -- Variable: undo-auto-current-boundary-timer
      Some buffers, such as process buffers, can change even when no
      commands are executing.  In these cases, ‘undo-boundary’ is
      normally called periodically by the timer in this variable.
      Setting this variable to non-‘nil’ prevents this behavior.
 
  -- Variable: undo-in-progress
      This variable is normally ‘nil’, but the undo commands bind it to
      ‘t’.  This is so that various kinds of change hooks can tell when
      they’re being called for the sake of undoing.
 
  -- Function: primitive-undo count list
      This is the basic function for undoing elements of an undo list.
      It undoes the first COUNT elements of LIST, returning the rest of
      LIST.
 
      ‘primitive-undo’ adds elements to the buffer’s undo list when it
      changes the buffer.  Undo commands avoid confusion by saving the
      undo list value at the beginning of a sequence of undo operations.
      Then the undo operations use and update the saved value.  The new
      elements added by undoing are not part of this saved value, so they
      don’t interfere with continuing to undo.
 
      This function does not bind ‘undo-in-progress’.