diff options
| author | Aaron S. Hawley | 2013-01-08 14:13:31 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2013-01-08 14:13:31 -0500 |
| commit | 3bace969f386056cedeaba7ac3661167d6d60190 (patch) | |
| tree | d4dddc07a157d2f2be055c1d0a879d23d292de68 /src/undo.c | |
| parent | 1c851e98b60d08404e5138b67ccf5b9d72fb4e47 (diff) | |
| download | emacs-3bace969f386056cedeaba7ac3661167d6d60190.tar.gz emacs-3bace969f386056cedeaba7ac3661167d6d60190.zip | |
* lisp/simple.el (primitive-undo): Move from undo.c.
* src/undo.c (Fprimitive_undo): Move to simple.el.
(syms_of_undo): Remove declaration for Sprimitive_undo.
* test/automated/undo-tests.el: New file.
Diffstat (limited to 'src/undo.c')
| -rw-r--r-- | src/undo.c | 212 |
1 files changed, 0 insertions, 212 deletions
diff --git a/src/undo.c b/src/undo.c index 2626fd4ccfe..63edc8e9b8d 100644 --- a/src/undo.c +++ b/src/undo.c | |||
| @@ -452,217 +452,6 @@ user_error (const char *msg) | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | 454 | ||
| 455 | DEFUN ("primitive-undo", Fprimitive_undo, Sprimitive_undo, 2, 2, 0, | ||
| 456 | doc: /* Undo N records from the front of the list LIST. | ||
| 457 | Return what remains of the list. */) | ||
| 458 | (Lisp_Object n, Lisp_Object list) | ||
| 459 | { | ||
| 460 | struct gcpro gcpro1, gcpro2; | ||
| 461 | Lisp_Object next; | ||
| 462 | ptrdiff_t count = SPECPDL_INDEX (); | ||
| 463 | register EMACS_INT arg; | ||
| 464 | Lisp_Object oldlist; | ||
| 465 | int did_apply = 0; | ||
| 466 | |||
| 467 | #if 0 /* This is a good feature, but would make undo-start | ||
| 468 | unable to do what is expected. */ | ||
| 469 | Lisp_Object tem; | ||
| 470 | |||
| 471 | /* If the head of the list is a boundary, it is the boundary | ||
| 472 | preceding this command. Get rid of it and don't count it. */ | ||
| 473 | tem = Fcar (list); | ||
| 474 | if (NILP (tem)) | ||
| 475 | list = Fcdr (list); | ||
| 476 | #endif | ||
| 477 | |||
| 478 | CHECK_NUMBER (n); | ||
| 479 | arg = XINT (n); | ||
| 480 | next = Qnil; | ||
| 481 | GCPRO2 (next, list); | ||
| 482 | /* I don't think we need to gcpro oldlist, as we use it only | ||
| 483 | to check for EQ. ++kfs */ | ||
| 484 | |||
| 485 | /* In a writable buffer, enable undoing read-only text that is so | ||
| 486 | because of text properties. */ | ||
| 487 | if (NILP (BVAR (current_buffer, read_only))) | ||
| 488 | specbind (Qinhibit_read_only, Qt); | ||
| 489 | |||
| 490 | /* Don't let `intangible' properties interfere with undo. */ | ||
| 491 | specbind (Qinhibit_point_motion_hooks, Qt); | ||
| 492 | |||
| 493 | oldlist = BVAR (current_buffer, undo_list); | ||
| 494 | |||
| 495 | while (arg > 0) | ||
| 496 | { | ||
| 497 | while (CONSP (list)) | ||
| 498 | { | ||
| 499 | next = XCAR (list); | ||
| 500 | list = XCDR (list); | ||
| 501 | /* Exit inner loop at undo boundary. */ | ||
| 502 | if (NILP (next)) | ||
| 503 | break; | ||
| 504 | /* Handle an integer by setting point to that value. */ | ||
| 505 | if (INTEGERP (next)) | ||
| 506 | SET_PT (clip_to_bounds (BEGV, XINT (next), ZV)); | ||
| 507 | else if (CONSP (next)) | ||
| 508 | { | ||
| 509 | Lisp_Object car, cdr; | ||
| 510 | |||
| 511 | car = XCAR (next); | ||
| 512 | cdr = XCDR (next); | ||
| 513 | if (EQ (car, Qt)) | ||
| 514 | { | ||
| 515 | /* Element (t . TIME) records previous modtime. | ||
| 516 | Preserve any flag of NONEXISTENT_MODTIME_NSECS or | ||
| 517 | UNKNOWN_MODTIME_NSECS. */ | ||
| 518 | struct buffer *base_buffer = current_buffer; | ||
| 519 | EMACS_TIME mod_time; | ||
| 520 | |||
| 521 | if (CONSP (cdr) | ||
| 522 | && CONSP (XCDR (cdr)) | ||
| 523 | && CONSP (XCDR (XCDR (cdr))) | ||
| 524 | && CONSP (XCDR (XCDR (XCDR (cdr)))) | ||
| 525 | && INTEGERP (XCAR (XCDR (XCDR (XCDR (cdr))))) | ||
| 526 | && XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) < 0) | ||
| 527 | mod_time = | ||
| 528 | (make_emacs_time | ||
| 529 | (0, XINT (XCAR (XCDR (XCDR (XCDR (cdr))))) / 1000)); | ||
| 530 | else | ||
| 531 | mod_time = lisp_time_argument (cdr); | ||
| 532 | |||
| 533 | if (current_buffer->base_buffer) | ||
| 534 | base_buffer = current_buffer->base_buffer; | ||
| 535 | |||
| 536 | /* If this records an obsolete save | ||
| 537 | (not matching the actual disk file) | ||
| 538 | then don't mark unmodified. */ | ||
| 539 | if (EMACS_TIME_NE (mod_time, base_buffer->modtime)) | ||
| 540 | continue; | ||
| 541 | #ifdef CLASH_DETECTION | ||
| 542 | Funlock_buffer (); | ||
| 543 | #endif /* CLASH_DETECTION */ | ||
| 544 | Fset_buffer_modified_p (Qnil); | ||
| 545 | } | ||
| 546 | else if (EQ (car, Qnil)) | ||
| 547 | { | ||
| 548 | /* Element (nil PROP VAL BEG . END) is property change. */ | ||
| 549 | Lisp_Object beg, end, prop, val; | ||
| 550 | |||
| 551 | prop = Fcar (cdr); | ||
| 552 | cdr = Fcdr (cdr); | ||
| 553 | val = Fcar (cdr); | ||
| 554 | cdr = Fcdr (cdr); | ||
| 555 | beg = Fcar (cdr); | ||
| 556 | end = Fcdr (cdr); | ||
| 557 | |||
| 558 | if (XINT (beg) < BEGV || XINT (end) > ZV) | ||
| 559 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 560 | Fput_text_property (beg, end, prop, val, Qnil); | ||
| 561 | } | ||
| 562 | else if (INTEGERP (car) && INTEGERP (cdr)) | ||
| 563 | { | ||
| 564 | /* Element (BEG . END) means range was inserted. */ | ||
| 565 | |||
| 566 | if (XINT (car) < BEGV | ||
| 567 | || XINT (cdr) > ZV) | ||
| 568 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 569 | /* Set point first thing, so that undoing this undo | ||
| 570 | does not send point back to where it is now. */ | ||
| 571 | Fgoto_char (car); | ||
| 572 | Fdelete_region (car, cdr); | ||
| 573 | } | ||
| 574 | else if (EQ (car, Qapply)) | ||
| 575 | { | ||
| 576 | /* Element (apply FUN . ARGS) means call FUN to undo. */ | ||
| 577 | struct buffer *save_buffer = current_buffer; | ||
| 578 | |||
| 579 | car = Fcar (cdr); | ||
| 580 | cdr = Fcdr (cdr); | ||
| 581 | if (INTEGERP (car)) | ||
| 582 | { | ||
| 583 | /* Long format: (apply DELTA START END FUN . ARGS). */ | ||
| 584 | Lisp_Object delta = car; | ||
| 585 | Lisp_Object start = Fcar (cdr); | ||
| 586 | Lisp_Object end = Fcar (Fcdr (cdr)); | ||
| 587 | Lisp_Object start_mark = Fcopy_marker (start, Qnil); | ||
| 588 | Lisp_Object end_mark = Fcopy_marker (end, Qt); | ||
| 589 | |||
| 590 | cdr = Fcdr (Fcdr (cdr)); | ||
| 591 | apply1 (Fcar (cdr), Fcdr (cdr)); | ||
| 592 | |||
| 593 | /* Check that the function did what the entry said it | ||
| 594 | would do. */ | ||
| 595 | if (!EQ (start, Fmarker_position (start_mark)) | ||
| 596 | || (XINT (delta) + XINT (end) | ||
| 597 | != marker_position (end_mark))) | ||
| 598 | error ("Changes to be undone by function different than announced"); | ||
| 599 | Fset_marker (start_mark, Qnil, Qnil); | ||
| 600 | Fset_marker (end_mark, Qnil, Qnil); | ||
| 601 | } | ||
| 602 | else | ||
| 603 | apply1 (car, cdr); | ||
| 604 | |||
| 605 | if (save_buffer != current_buffer) | ||
| 606 | error ("Undo function switched buffer"); | ||
| 607 | did_apply = 1; | ||
| 608 | } | ||
| 609 | else if (STRINGP (car) && INTEGERP (cdr)) | ||
| 610 | { | ||
| 611 | /* Element (STRING . POS) means STRING was deleted. */ | ||
| 612 | Lisp_Object membuf; | ||
| 613 | EMACS_INT pos = XINT (cdr); | ||
| 614 | |||
| 615 | membuf = car; | ||
| 616 | if (pos < 0) | ||
| 617 | { | ||
| 618 | if (-pos < BEGV || -pos > ZV) | ||
| 619 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 620 | SET_PT (-pos); | ||
| 621 | Finsert (1, &membuf); | ||
| 622 | } | ||
| 623 | else | ||
| 624 | { | ||
| 625 | if (pos < BEGV || pos > ZV) | ||
| 626 | user_error ("Changes to be undone are outside visible portion of buffer"); | ||
| 627 | SET_PT (pos); | ||
| 628 | |||
| 629 | /* Now that we record marker adjustments | ||
| 630 | (caused by deletion) for undo, | ||
| 631 | we should always insert after markers, | ||
| 632 | so that undoing the marker adjustments | ||
| 633 | put the markers back in the right place. */ | ||
| 634 | Finsert (1, &membuf); | ||
| 635 | SET_PT (pos); | ||
| 636 | } | ||
| 637 | } | ||
| 638 | else if (MARKERP (car) && INTEGERP (cdr)) | ||
| 639 | { | ||
| 640 | /* (MARKER . INTEGER) means a marker MARKER | ||
| 641 | was adjusted by INTEGER. */ | ||
| 642 | if (XMARKER (car)->buffer) | ||
| 643 | Fset_marker (car, | ||
| 644 | make_number (marker_position (car) - XINT (cdr)), | ||
| 645 | Fmarker_buffer (car)); | ||
| 646 | } | ||
| 647 | } | ||
| 648 | } | ||
| 649 | arg--; | ||
| 650 | } | ||
| 651 | |||
| 652 | |||
| 653 | /* Make sure an apply entry produces at least one undo entry, | ||
| 654 | so the test in `undo' for continuing an undo series | ||
| 655 | will work right. */ | ||
| 656 | if (did_apply | ||
| 657 | && EQ (oldlist, BVAR (current_buffer, undo_list))) | ||
| 658 | bset_undo_list | ||
| 659 | (current_buffer, | ||
| 660 | Fcons (list3 (Qapply, Qcdr, Qnil), BVAR (current_buffer, undo_list))); | ||
| 661 | |||
| 662 | UNGCPRO; | ||
| 663 | return unbind_to (count, list); | ||
| 664 | } | ||
| 665 | |||
| 666 | void | 455 | void |
| 667 | syms_of_undo (void) | 456 | syms_of_undo (void) |
| 668 | { | 457 | { |
| @@ -675,7 +464,6 @@ syms_of_undo (void) | |||
| 675 | last_undo_buffer = NULL; | 464 | last_undo_buffer = NULL; |
| 676 | last_boundary_buffer = NULL; | 465 | last_boundary_buffer = NULL; |
| 677 | 466 | ||
| 678 | defsubr (&Sprimitive_undo); | ||
| 679 | defsubr (&Sundo_boundary); | 467 | defsubr (&Sundo_boundary); |
| 680 | 468 | ||
| 681 | DEFVAR_INT ("undo-limit", undo_limit, | 469 | DEFVAR_INT ("undo-limit", undo_limit, |