Exemple #1
0
/*
 * Revert an action.  Return the next undo entry.
 */
static Undo *
revert_action (Undo * up)
{
  size_t i;
  Point pt;

  pt.n = up->n;
  pt.o = up->o;

  doing_undo = true;

  if (up->type == UNDO_END_SEQUENCE)
    {
      undo_save (UNDO_START_SEQUENCE, pt, 0, 0);
      up = up->next;
      while (up->type != UNDO_START_SEQUENCE)
        up = revert_action (up);
      pt.n = up->n;
      pt.o = up->o;
      undo_save (UNDO_END_SEQUENCE, pt, 0, 0);
      goto_point (pt);
      return up->next;
    }

  goto_point (pt);

  if (up->type == UNDO_REPLACE_BLOCK)
    {
      undo_save (UNDO_REPLACE_BLOCK, pt,
                 up->block.size, up->block.osize);
      undo_nosave = true;
      for (i = 0; i < up->block.size; ++i)
        delete_char ();
      insert_nstring (astr_cstr (up->block.text), up->block.osize);
      undo_nosave = false;
    }

  doing_undo = false;

  if (up->unchanged)
    set_buffer_modified (cur_bp, false);

  return up->next;
}
/*
 * Revert an action.  Return the next undo entry.
 */
static undop revert_action(undop up)
{
	int i;

	doing_undo = TRUE;

	if (up->type == UNDO_END_SEQUENCE) {
		undo_save(UNDO_START_SEQUENCE, up->pointn, up->pointo, 0, 0);
		up = up->next;
		while (up->type != UNDO_START_SEQUENCE) {
			revert_action(up);
			up = up->next;
		}
		undo_save(UNDO_END_SEQUENCE, up->pointn, up->pointo, 0, 0);
		goto_point(up->pointn, up->pointo);
		return up->next;
	}

	goto_point(up->pointn, up->pointo);

	switch (up->type) {
	case UNDO_INSERT_CHAR:
		if (up->delta.c == '\n')
			insert_newline();
		else
			insert_char_in_insert_mode(up->delta.c);
		break;
	case UNDO_INTERCALATE_CHAR:
		if (up->delta.c == '\n')
			intercalate_newline();
		else
			intercalate_char(up->delta.c);
		break;
	case UNDO_INSERT_BLOCK:
		undo_save(UNDO_REMOVE_BLOCK, up->pointn, up->pointo, up->delta.block.size, 0);
		undo_nosave = TRUE;
		for (i = 0; i < up->delta.block.size; i++)
			if (up->delta.block.text[i] != '\n')
				insert_char(up->delta.block.text[i]);
			else
				insert_newline();
		undo_nosave = FALSE;
		break;
	case UNDO_REMOVE_CHAR:
		FUNCALL(delete_char);
		break;
	case UNDO_REMOVE_BLOCK:
		undo_save(UNDO_INSERT_BLOCK, up->pointn, up->pointo, up->delta.block.size, 0);
		undo_nosave = TRUE;
		for (i = 0; i < up->delta.block.size; i++)
			FUNCALL(delete_char);
		undo_nosave = FALSE;
		break;
	case UNDO_REPLACE_CHAR:
		undo_save(UNDO_REPLACE_CHAR, up->pointn, up->pointo,
			  cur_wp->pointp->text[up->pointo], 0);
		cur_wp->pointp->text[up->pointo] = up->delta.c;
		cur_bp->flags |= BFLAG_MODIFIED;
		if (cur_bp->flags & BFLAG_FONTLOCK)
			font_lock_reset_anchors(cur_bp, cur_wp->pointp);
		break;
	case UNDO_REPLACE_BLOCK:
		undo_save(UNDO_REPLACE_BLOCK, up->pointn, up->pointo,
			  up->delta.block.size, up->delta.block.osize);
		undo_nosave = TRUE;
		for (i = 0; i < up->delta.block.size; i++)
			FUNCALL(delete_char);
		for (i = 0; i < up->delta.block.osize; i++)
			if (up->delta.block.text[i] != '\n')
				insert_char(up->delta.block.text[i]);
			else
				insert_newline();
		undo_nosave = FALSE;
		break;
	}

	doing_undo = FALSE;

	return up->next;
}