Exemplo n.º 1
0
/* Record that a deletion is about to take place, of the characters in
   STRING, at location BEG.  Optionally record adjustments for markers
   in the region STRING occupies in the current buffer.  */
void
record_delete (ptrdiff_t beg, Lisp_Object string, bool record_markers)
{
  Lisp_Object sbeg;

  if (EQ (BVAR (current_buffer, undo_list), Qt))
    return;

  if (point_before_last_command_or_undo != beg
      && buffer_before_last_command_or_undo == current_buffer)
    record_point (point_before_last_command_or_undo);

  if (PT == beg + SCHARS (string))
    {
      XSETINT (sbeg, -beg);
      prepare_record ();
    }
  else
    {
      XSETFASTINT (sbeg, beg);
      prepare_record ();
    }

  /* primitive-undo assumes marker adjustments are recorded
     immediately before the deletion is recorded.  See bug 16818
     discussion.  */
  if (record_markers)
    record_marker_adjustments (beg, beg + SCHARS (string));

  bset_undo_list
    (current_buffer,
     Fcons (Fcons (string, sbeg), BVAR (current_buffer, undo_list)));
}
Exemplo n.º 2
0
Arquivo: undo.c Projeto: Wilfred/emacs
void
record_insert (ptrdiff_t beg, ptrdiff_t length)
{
  Lisp_Object lbeg, lend;

  if (EQ (BVAR (current_buffer, undo_list), Qt))
    return;

  prepare_record ();

  record_point (beg);

  /* If this is following another insertion and consecutive with it
     in the buffer, combine the two.  */
  if (CONSP (BVAR (current_buffer, undo_list)))
    {
      Lisp_Object elt;
      elt = XCAR (BVAR (current_buffer, undo_list));
      if (CONSP (elt)
	  && INTEGERP (XCAR (elt))
	  && INTEGERP (XCDR (elt))
	  && XINT (XCDR (elt)) == beg)
	{
	  XSETCDR (elt, make_number (beg + length));
	  return;
	}
    }

  XSETFASTINT (lbeg, beg);
  XSETINT (lend, beg + length);
  bset_undo_list (current_buffer,
		  Fcons (Fcons (lbeg, lend), BVAR (current_buffer, undo_list)));
}
Exemplo n.º 3
0
/* Record point as it was at beginning of this command.
   PT is the position of point that will naturally occur as a result of the
   undo record that will be added just after this command terminates.  */
static void
record_point (ptrdiff_t pt)
{
  /* Don't record position of pt when undo_inhibit_record_point holds.  */
  if (undo_inhibit_record_point)
    return;

  bool at_boundary;

  at_boundary = ! CONSP (BVAR (current_buffer, undo_list))
                || NILP (XCAR (BVAR (current_buffer, undo_list)));

  prepare_record ();

  /* If we are just after an undo boundary, and
     point wasn't at start of deleted range, record where it was.  */
  if (at_boundary)
    bset_undo_list (current_buffer,
		    Fcons (make_number (pt),
			   BVAR (current_buffer, undo_list)));
}
Exemplo n.º 4
0
Arquivo: undo.c Projeto: Wilfred/emacs
void
record_property_change (ptrdiff_t beg, ptrdiff_t length,
			Lisp_Object prop, Lisp_Object value,
			Lisp_Object buffer)
{
  Lisp_Object lbeg, lend, entry;
  struct buffer *buf = XBUFFER (buffer);

  if (EQ (BVAR (buf, undo_list), Qt))
    return;

  prepare_record();

  if (MODIFF <= SAVE_MODIFF)
    record_first_change ();

  XSETINT (lbeg, beg);
  XSETINT (lend, beg + length);
  entry = Fcons (Qnil, Fcons (prop, Fcons (value, Fcons (lbeg, lend))));
  bset_undo_list (current_buffer,
		  Fcons (entry, BVAR (current_buffer, undo_list)));
}
Exemplo n.º 5
0
Arquivo: undo.c Projeto: Wilfred/emacs
static void
record_marker_adjustments (ptrdiff_t from, ptrdiff_t to)
{
  Lisp_Object marker;
  register struct Lisp_Marker *m;
  register ptrdiff_t charpos, adjustment;

  prepare_record();

  for (m = BUF_MARKERS (current_buffer); m; m = m->next)
    {
      charpos = m->charpos;
      eassert (charpos <= Z);

      if (from <= charpos && charpos <= to)
        {
          /* insertion_type nil markers will end up at the beginning of
             the re-inserted text after undoing a deletion, and must be
             adjusted to move them to the correct place.

             insertion_type t markers will automatically move forward
             upon re-inserting the deleted text, so we have to arrange
             for them to move backward to the correct position.  */
          adjustment = (m->insertion_type ? to : from) - charpos;

          if (adjustment)
            {
              XSETMISC (marker, m);
              bset_undo_list
                (current_buffer,
                 Fcons (Fcons (marker, make_number (adjustment)),
                        BVAR (current_buffer, undo_list)));
            }
        }
    }
}