diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/insdel.c | 317 |
1 files changed, 259 insertions, 58 deletions
diff --git a/src/insdel.c b/src/insdel.c index ded0fca99d8..a3afd75b5c5 100644 --- a/src/insdel.c +++ b/src/insdel.c | |||
| @@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */ | |||
| 33 | 33 | ||
| 34 | #define min(x, y) ((x) < (y) ? (x) : (y)) | 34 | #define min(x, y) ((x) < (y) ? (x) : (y)) |
| 35 | 35 | ||
| 36 | static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int)); | 36 | static void insert_from_string_1 P_ ((Lisp_Object, int, int, int, int, int, int)); |
| 37 | static void insert_from_buffer_1 (); | 37 | static void insert_from_buffer_1 (); |
| 38 | static void gap_left P_ ((int, int, int)); | 38 | static void gap_left P_ ((int, int, int)); |
| 39 | static void gap_right P_ ((int, int)); | 39 | static void gap_right P_ ((int, int)); |
| @@ -63,6 +63,8 @@ Lisp_Object combine_after_change_list; | |||
| 63 | /* Buffer which combine_after_change_list is about. */ | 63 | /* Buffer which combine_after_change_list is about. */ |
| 64 | Lisp_Object combine_after_change_buffer; | 64 | Lisp_Object combine_after_change_buffer; |
| 65 | 65 | ||
| 66 | #define DEFAULT_NONASCII_INSERT_OFFSET 0x800 | ||
| 67 | |||
| 66 | /* Move gap to position CHARPOS. | 68 | /* Move gap to position CHARPOS. |
| 67 | Note that this can quit! */ | 69 | Note that this can quit! */ |
| 68 | 70 | ||
| @@ -262,7 +264,7 @@ gap_right (charpos, bytepos) | |||
| 262 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 264 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 263 | QUIT; | 265 | QUIT; |
| 264 | } | 266 | } |
| 265 | 267 | ||
| 266 | /* Add AMOUNT to the byte position of every marker in the current buffer | 268 | /* Add AMOUNT to the byte position of every marker in the current buffer |
| 267 | whose current byte position is between FROM (exclusive) and TO (inclusive). | 269 | whose current byte position is between FROM (exclusive) and TO (inclusive). |
| 268 | 270 | ||
| @@ -324,7 +326,7 @@ adjust_markers_gap_motion (from, to, amount) | |||
| 324 | } | 326 | } |
| 325 | #endif | 327 | #endif |
| 326 | } | 328 | } |
| 327 | 329 | ||
| 328 | /* Adjust all markers for a deletion | 330 | /* Adjust all markers for a deletion |
| 329 | whose range in bytes is FROM_BYTE to TO_BYTE. | 331 | whose range in bytes is FROM_BYTE to TO_BYTE. |
| 330 | The range in charpos is FROM to TO. | 332 | The range in charpos is FROM to TO. |
| @@ -389,7 +391,7 @@ adjust_markers_for_delete (from, from_byte, to, to_byte) | |||
| 389 | marker = m->chain; | 391 | marker = m->chain; |
| 390 | } | 392 | } |
| 391 | } | 393 | } |
| 392 | 394 | ||
| 393 | /* Adjust markers for an insertion at CHARPOS / BYTEPOS | 395 | /* Adjust markers for an insertion at CHARPOS / BYTEPOS |
| 394 | consisting of NCHARS chars, which are NBYTES bytes. | 396 | consisting of NCHARS chars, which are NBYTES bytes. |
| 395 | 397 | ||
| @@ -542,7 +544,107 @@ make_gap (nbytes_added) | |||
| 542 | Vinhibit_quit = tem; | 544 | Vinhibit_quit = tem; |
| 543 | } | 545 | } |
| 544 | 546 | ||
| 547 | /* Copy NBYTES bytes of text from FROM_ADDR to TO_ADDR. | ||
| 548 | FROM_MULTIBYTE says whether the incoming text is multibyte. | ||
| 549 | TO_MULTIBYTE says whether to store the text as multibyte. | ||
| 550 | If FROM_MULTIBYTE != TO_MULTIBYTE, we convert. | ||
| 551 | |||
| 552 | Return the number of bytes stored at TO_ADDR. */ | ||
| 553 | |||
| 554 | int | ||
| 555 | copy_text (from_addr, to_addr, nbytes, | ||
| 556 | from_multibyte, to_multibyte) | ||
| 557 | unsigned char *from_addr; | ||
| 558 | unsigned char *to_addr; | ||
| 559 | int nbytes; | ||
| 560 | int from_multibyte, to_multibyte; | ||
| 561 | { | ||
| 562 | if (from_multibyte == to_multibyte) | ||
| 563 | { | ||
| 564 | bcopy (from_addr, to_addr, nbytes); | ||
| 565 | return nbytes; | ||
| 566 | } | ||
| 567 | else if (from_multibyte) | ||
| 568 | { | ||
| 569 | int nchars = 0; | ||
| 570 | int bytes_left = nbytes; | ||
| 571 | |||
| 572 | /* Convert multibyte to single byte. */ | ||
| 573 | while (bytes_left > 0) | ||
| 574 | { | ||
| 575 | int thislen, c; | ||
| 576 | c = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen); | ||
| 577 | *to_addr++ = (c & 0177) + 0200; | ||
| 578 | from_addr += thislen; | ||
| 579 | bytes_left--; | ||
| 580 | nchars++; | ||
| 581 | } | ||
| 582 | return nchars; | ||
| 583 | } | ||
| 584 | else | ||
| 585 | { | ||
| 586 | unsigned char *initial_to_addr = to_addr; | ||
| 587 | |||
| 588 | /* Convert single-byte to multibyte. */ | ||
| 589 | while (nbytes > 0) | ||
| 590 | { | ||
| 591 | int c = *from_addr++; | ||
| 592 | unsigned char workbuf[4], *str; | ||
| 593 | int len; | ||
| 594 | |||
| 595 | if (c >= 0200 && c < 0400) | ||
| 596 | { | ||
| 597 | if (nonascii_insert_offset > 0) | ||
| 598 | c += nonascii_insert_offset; | ||
| 599 | else | ||
| 600 | c += DEFAULT_NONASCII_INSERT_OFFSET; | ||
| 601 | |||
| 602 | len = CHAR_STRING (c, workbuf, str); | ||
| 603 | bcopy (str, to_addr, len); | ||
| 604 | to_addr += len; | ||
| 605 | nbytes--; | ||
| 606 | } | ||
| 607 | else | ||
| 608 | /* Special case for speed. */ | ||
| 609 | *to_addr++ = c, nbytes--; | ||
| 610 | } | ||
| 611 | return to_addr - initial_to_addr; | ||
| 612 | } | ||
| 613 | } | ||
| 614 | |||
| 615 | /* Return the number of bytes it would take | ||
| 616 | to convert some single-byte text to multibyte. | ||
| 617 | The single-byte text consists of NBYTES bytes at PTR. */ | ||
| 618 | |||
| 619 | int | ||
| 620 | count_size_as_multibyte (ptr, nbytes) | ||
| 621 | unsigned char *ptr; | ||
| 622 | int nbytes; | ||
| 623 | { | ||
| 624 | int i; | ||
| 625 | int outgoing_nbytes = 0; | ||
| 626 | |||
| 627 | for (i = 0; i < nbytes; i++) | ||
| 628 | { | ||
| 629 | unsigned int c = *ptr++; | ||
| 630 | if (c >= 0200 && c < 0400) | ||
| 631 | { | ||
| 632 | if (nonascii_insert_offset > 0) | ||
| 633 | c += nonascii_insert_offset; | ||
| 634 | else | ||
| 635 | c += DEFAULT_NONASCII_INSERT_OFFSET; | ||
| 636 | } | ||
| 637 | outgoing_nbytes += XINT (Fchar_bytes (make_number (c))); | ||
| 638 | } | ||
| 639 | |||
| 640 | return outgoing_nbytes; | ||
| 641 | } | ||
| 642 | |||
| 545 | /* Insert a string of specified length before point. | 643 | /* Insert a string of specified length before point. |
| 644 | This function judges multibyteness based on | ||
| 645 | enable_multibyte_characters in the current buffer; | ||
| 646 | it never converts between single-byte and multibyte. | ||
| 647 | |||
| 546 | DO NOT use this for the contents of a Lisp string or a Lisp buffer! | 648 | DO NOT use this for the contents of a Lisp string or a Lisp buffer! |
| 547 | prepare_to_modify_buffer could relocate the text. */ | 649 | prepare_to_modify_buffer could relocate the text. */ |
| 548 | 650 | ||
| @@ -559,6 +661,8 @@ insert (string, nbytes) | |||
| 559 | } | 661 | } |
| 560 | } | 662 | } |
| 561 | 663 | ||
| 664 | /* Likewise, but inherit text properties from neighboring characters. */ | ||
| 665 | |||
| 562 | void | 666 | void |
| 563 | insert_and_inherit (string, nbytes) | 667 | insert_and_inherit (string, nbytes) |
| 564 | register unsigned char *string; | 668 | register unsigned char *string; |
| @@ -572,19 +676,28 @@ insert_and_inherit (string, nbytes) | |||
| 572 | } | 676 | } |
| 573 | } | 677 | } |
| 574 | 678 | ||
| 575 | /* Insert the character C before point */ | 679 | /* Insert the character C before point. Do not inherit text properties. */ |
| 576 | 680 | ||
| 577 | void | 681 | void |
| 578 | insert_char (c) | 682 | insert_char (c) |
| 579 | int c; | 683 | int c; |
| 580 | { | 684 | { |
| 581 | unsigned char workbuf[4], *str; | 685 | unsigned char workbuf[4], *str; |
| 582 | int len = CHAR_STRING (c, workbuf, str); | 686 | int len; |
| 687 | |||
| 688 | if (! NILP (current_buffer->enable_multibyte_characters)) | ||
| 689 | len = CHAR_STRING (c, workbuf, str); | ||
| 690 | else | ||
| 691 | { | ||
| 692 | len = 1; | ||
| 693 | workbuf[0] = c; | ||
| 694 | str = workbuf; | ||
| 695 | } | ||
| 583 | 696 | ||
| 584 | insert (str, len); | 697 | insert (str, len); |
| 585 | } | 698 | } |
| 586 | 699 | ||
| 587 | /* Insert the null-terminated string S before point */ | 700 | /* Insert the null-terminated string S before point. */ |
| 588 | 701 | ||
| 589 | void | 702 | void |
| 590 | insert_string (s) | 703 | insert_string (s) |
| @@ -612,6 +725,8 @@ insert_before_markers (string, nbytes) | |||
| 612 | } | 725 | } |
| 613 | } | 726 | } |
| 614 | 727 | ||
| 728 | /* Likewise, but inherit text properties from neighboring characters. */ | ||
| 729 | |||
| 615 | void | 730 | void |
| 616 | insert_before_markers_and_inherit (string, nbytes) | 731 | insert_before_markers_and_inherit (string, nbytes) |
| 617 | unsigned char *string; | 732 | unsigned char *string; |
| @@ -625,7 +740,7 @@ insert_before_markers_and_inherit (string, nbytes) | |||
| 625 | signal_after_change (opoint, 0, PT - opoint); | 740 | signal_after_change (opoint, 0, PT - opoint); |
| 626 | } | 741 | } |
| 627 | } | 742 | } |
| 628 | 743 | ||
| 629 | /* Subroutine used by the insert functions above. */ | 744 | /* Subroutine used by the insert functions above. */ |
| 630 | 745 | ||
| 631 | void | 746 | void |
| @@ -678,49 +793,100 @@ insert_1 (string, nbytes, inherit, prepare, before_markers) | |||
| 678 | Qnil, Qnil); | 793 | Qnil, Qnil); |
| 679 | #endif | 794 | #endif |
| 680 | } | 795 | } |
| 796 | |||
| 797 | /* Insert a sequence of NCHARS chars which occupy NBYTES bytes | ||
| 798 | starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS | ||
| 799 | are the same as in insert_1. */ | ||
| 800 | |||
| 801 | void | ||
| 802 | insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers) | ||
| 803 | register unsigned char *string; | ||
| 804 | register int nchars, nbytes; | ||
| 805 | int inherit, prepare, before_markers; | ||
| 806 | { | ||
| 807 | register Lisp_Object temp; | ||
| 808 | |||
| 809 | if (prepare) | ||
| 810 | prepare_to_modify_buffer (PT, PT, NULL); | ||
| 811 | |||
| 812 | if (PT != GPT) | ||
| 813 | move_gap_both (PT, PT_BYTE); | ||
| 814 | if (GAP_SIZE < nbytes) | ||
| 815 | make_gap (nbytes - GAP_SIZE); | ||
| 816 | |||
| 817 | record_insert (PT, nchars); | ||
| 818 | MODIFF++; | ||
| 819 | |||
| 820 | bcopy (string, GPT_ADDR, nbytes); | ||
| 821 | |||
| 822 | #ifdef USE_TEXT_PROPERTIES | ||
| 823 | if (BUF_INTERVALS (current_buffer) != 0) | ||
| 824 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */ | ||
| 825 | offset_intervals (current_buffer, PT, nchars); | ||
| 826 | #endif | ||
| 827 | |||
| 828 | GAP_SIZE -= nbytes; | ||
| 829 | GPT += nchars; | ||
| 830 | ZV += nchars; | ||
| 831 | Z += nchars; | ||
| 832 | GPT_BYTE += nbytes; | ||
| 833 | ZV_BYTE += nbytes; | ||
| 834 | Z_BYTE += nbytes; | ||
| 835 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | ||
| 836 | adjust_overlays_for_insert (PT, nchars); | ||
| 837 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, | ||
| 838 | before_markers); | ||
| 839 | adjust_point (nchars, nbytes); | ||
| 840 | |||
| 841 | if (GPT_BYTE < GPT) | ||
| 842 | abort (); | ||
| 843 | |||
| 844 | #ifdef USE_TEXT_PROPERTIES | ||
| 845 | if (!inherit && BUF_INTERVALS (current_buffer) != 0) | ||
| 846 | Fset_text_properties (make_number (PT - nchars), make_number (PT), | ||
| 847 | Qnil, Qnil); | ||
| 848 | #endif | ||
| 849 | } | ||
| 681 | 850 | ||
| 682 | /* Insert the part of the text of STRING, a Lisp object assumed to be | 851 | /* Insert the part of the text of STRING, a Lisp object assumed to be |
| 683 | of type string, consisting of the LENGTH characters starting at | 852 | of type string, consisting of the LENGTH characters (LENGTH_BYTE bytes) |
| 684 | position POS. If the text of STRING has properties, they are absorbed | 853 | starting at position POS / POS_BYTE. If the text of STRING has properties, |
| 685 | into the buffer. | 854 | copy them into the buffer. |
| 686 | 855 | ||
| 687 | It does not work to use `insert' for this, because a GC could happen | 856 | It does not work to use `insert' for this, because a GC could happen |
| 688 | before we bcopy the stuff into the buffer, and relocate the string | 857 | before we bcopy the stuff into the buffer, and relocate the string |
| 689 | without insert noticing. */ | 858 | without insert noticing. */ |
| 690 | 859 | ||
| 691 | void | 860 | void |
| 692 | insert_from_string (string, pos, length, inherit) | 861 | insert_from_string (string, pos, pos_byte, length, length_byte, inherit) |
| 693 | Lisp_Object string; | 862 | Lisp_Object string; |
| 694 | register int pos, length; | 863 | register int pos, pos_byte, length, length_byte; |
| 695 | int inherit; | 864 | int inherit; |
| 696 | { | 865 | { |
| 697 | if (length > 0) | 866 | if (length > 0) |
| 698 | { | 867 | { |
| 699 | int opoint = PT; | 868 | int opoint = PT; |
| 700 | int nchars = chars_in_text (XSTRING (string)->data + pos, length); | 869 | insert_from_string_1 (string, pos, pos_byte, length, length_byte, |
| 701 | insert_from_string_1 (string, pos, length, nchars, inherit, 0); | 870 | inherit, 0); |
| 702 | signal_after_change (opoint, 0, PT - opoint); | 871 | signal_after_change (opoint, 0, PT - opoint); |
| 703 | } | 872 | } |
| 704 | } | 873 | } |
| 705 | 874 | ||
| 706 | /* Like `insert' except that all markers pointing at the place where | 875 | /* Like `insert_from_string' except that all markers pointing |
| 707 | the insertion happens are adjusted to point after it. | 876 | at the place where the insertion happens are adjusted to point after it. */ |
| 708 | Don't use this function to insert part of a Lisp string, | ||
| 709 | since gc could happen and relocate it. */ | ||
| 710 | |||
| 711 | /* Insert part of a Lisp string, relocating markers after. */ | ||
| 712 | 877 | ||
| 713 | void | 878 | void |
| 714 | insert_from_string_before_markers (string, pos, length, inherit) | 879 | insert_from_string_before_markers (string, pos, pos_byte, |
| 880 | length, length_byte, inherit) | ||
| 715 | Lisp_Object string; | 881 | Lisp_Object string; |
| 716 | register int pos, length; | 882 | register int pos, pos_byte, length, length_byte; |
| 717 | int inherit; | 883 | int inherit; |
| 718 | { | 884 | { |
| 719 | if (length > 0) | 885 | if (length > 0) |
| 720 | { | 886 | { |
| 721 | int opoint = PT; | 887 | int opoint = PT; |
| 722 | int nchars = chars_in_text (XSTRING (string)->data + pos, length); | 888 | insert_from_string_1 (string, pos, pos_byte, length, length_byte, |
| 723 | insert_from_string_1 (string, pos, length, nchars, inherit, 1); | 889 | inherit, 1); |
| 724 | signal_after_change (opoint, 0, PT - opoint); | 890 | signal_after_change (opoint, 0, PT - opoint); |
| 725 | } | 891 | } |
| 726 | } | 892 | } |
| @@ -728,17 +894,29 @@ insert_from_string_before_markers (string, pos, length, inherit) | |||
| 728 | /* Subroutine of the insertion functions above. */ | 894 | /* Subroutine of the insertion functions above. */ |
| 729 | 895 | ||
| 730 | static void | 896 | static void |
| 731 | insert_from_string_1 (string, pos, nbytes, nchars, inherit, before_markers) | 897 | insert_from_string_1 (string, pos, pos_byte, nchars, nbytes, |
| 898 | inherit, before_markers) | ||
| 732 | Lisp_Object string; | 899 | Lisp_Object string; |
| 733 | register int pos, nbytes, nchars; | 900 | register int pos, pos_byte, nchars, nbytes; |
| 734 | int inherit, before_markers; | 901 | int inherit, before_markers; |
| 735 | { | 902 | { |
| 736 | register Lisp_Object temp; | 903 | register Lisp_Object temp; |
| 737 | struct gcpro gcpro1; | 904 | struct gcpro gcpro1; |
| 905 | int outgoing_nbytes = nbytes; | ||
| 906 | |||
| 907 | /* Make OUTGOING_NBYTES describe the text | ||
| 908 | as it will be inserted in this buffer. */ | ||
| 909 | |||
| 910 | if (NILP (current_buffer->enable_multibyte_characters)) | ||
| 911 | outgoing_nbytes = nchars; | ||
| 912 | else if (nchars == nbytes) | ||
| 913 | outgoing_nbytes | ||
| 914 | = count_size_as_multibyte (&XSTRING (string)->data[pos_byte], | ||
| 915 | nbytes); | ||
| 738 | 916 | ||
| 739 | /* Make sure point-max won't overflow after this insertion. */ | 917 | /* Make sure point-max won't overflow after this insertion. */ |
| 740 | XSETINT (temp, nbytes + Z_BYTE); | 918 | XSETINT (temp, outgoing_nbytes + Z); |
| 741 | if (nbytes + Z_BYTE != XINT (temp)) | 919 | if (outgoing_nbytes + Z != XINT (temp)) |
| 742 | error ("Maximum buffer size exceeded"); | 920 | error ("Maximum buffer size exceeded"); |
| 743 | 921 | ||
| 744 | GCPRO1 (string); | 922 | GCPRO1 (string); |
| @@ -747,13 +925,21 @@ insert_from_string_1 (string, pos, nbytes, nchars, inherit, before_markers) | |||
| 747 | if (PT != GPT) | 925 | if (PT != GPT) |
| 748 | move_gap_both (PT, PT_BYTE); | 926 | move_gap_both (PT, PT_BYTE); |
| 749 | if (GAP_SIZE < nbytes) | 927 | if (GAP_SIZE < nbytes) |
| 750 | make_gap (nbytes - GAP_SIZE); | 928 | make_gap (outgoing_nbytes - GAP_SIZE); |
| 751 | 929 | ||
| 752 | record_insert (PT, nchars); | 930 | record_insert (PT, nchars); |
| 753 | MODIFF++; | 931 | MODIFF++; |
| 754 | UNGCPRO; | 932 | UNGCPRO; |
| 755 | 933 | ||
| 756 | bcopy (XSTRING (string)->data, GPT_ADDR, nbytes); | 934 | /* Copy the string text into the buffer, perhaps converting |
| 935 | between single-byte and multibyte. */ | ||
| 936 | copy_text (XSTRING (string)->data + pos_byte, GPT_ADDR, nbytes, | ||
| 937 | /* If these are equal, it is a single-byte string. | ||
| 938 | Its chars are either ASCII, in which case copy_text | ||
| 939 | won't change it, or single-byte non-ASCII chars, | ||
| 940 | that need to be changed. */ | ||
| 941 | nchars != nbytes, | ||
| 942 | ! NILP (current_buffer->enable_multibyte_characters)); | ||
| 757 | 943 | ||
| 758 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | 944 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ |
| 759 | offset_intervals (current_buffer, PT, nchars); | 945 | offset_intervals (current_buffer, PT, nchars); |
| @@ -762,22 +948,22 @@ insert_from_string_1 (string, pos, nbytes, nchars, inherit, before_markers) | |||
| 762 | GPT += nchars; | 948 | GPT += nchars; |
| 763 | ZV += nchars; | 949 | ZV += nchars; |
| 764 | Z += nchars; | 950 | Z += nchars; |
| 765 | GPT_BYTE += nbytes; | 951 | GPT_BYTE += outgoing_nbytes; |
| 766 | ZV_BYTE += nbytes; | 952 | ZV_BYTE += outgoing_nbytes; |
| 767 | Z_BYTE += nbytes; | 953 | Z_BYTE += outgoing_nbytes; |
| 768 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 954 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 769 | adjust_overlays_for_insert (PT, nchars); | 955 | adjust_overlays_for_insert (PT, nchars); |
| 770 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, | 956 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, |
| 957 | PT_BYTE + outgoing_nbytes, | ||
| 771 | before_markers); | 958 | before_markers); |
| 772 | 959 | ||
| 773 | if (GPT_BYTE < GPT) | 960 | if (GPT_BYTE < GPT) |
| 774 | abort (); | 961 | abort (); |
| 775 | 962 | ||
| 776 | /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */ | ||
| 777 | graft_intervals_into_buffer (XSTRING (string)->intervals, PT, nchars, | 963 | graft_intervals_into_buffer (XSTRING (string)->intervals, PT, nchars, |
| 778 | current_buffer, inherit); | 964 | current_buffer, inherit); |
| 779 | 965 | ||
| 780 | adjust_point (nchars, nbytes); | 966 | adjust_point (nchars, outgoing_nbytes); |
| 781 | } | 967 | } |
| 782 | 968 | ||
| 783 | /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the | 969 | /* Insert text from BUF, NCHARS characters starting at CHARPOS, into the |
| @@ -812,19 +998,30 @@ insert_from_buffer_1 (buf, from, nchars, inherit) | |||
| 812 | int chunk; | 998 | int chunk; |
| 813 | int from_byte = buf_charpos_to_bytepos (buf, from); | 999 | int from_byte = buf_charpos_to_bytepos (buf, from); |
| 814 | int to_byte = buf_charpos_to_bytepos (buf, from + nchars); | 1000 | int to_byte = buf_charpos_to_bytepos (buf, from + nchars); |
| 815 | int nbytes = to_byte - from_byte; | 1001 | int incoming_nbytes = to_byte - from_byte; |
| 1002 | int outgoing_nbytes = incoming_nbytes; | ||
| 1003 | |||
| 1004 | /* Make OUTGOING_NBYTES describe the text | ||
| 1005 | as it will be inserted in this buffer. */ | ||
| 1006 | |||
| 1007 | if (NILP (current_buffer->enable_multibyte_characters)) | ||
| 1008 | outgoing_nbytes = nchars; | ||
| 1009 | else if (NILP (buf->enable_multibyte_characters)) | ||
| 1010 | outgoing_nbytes | ||
| 1011 | = count_size_as_multibyte (BUF_BYTE_ADDRESS (buf, from_byte), | ||
| 1012 | incoming_nbytes); | ||
| 816 | 1013 | ||
| 817 | /* Make sure point-max won't overflow after this insertion. */ | 1014 | /* Make sure point-max won't overflow after this insertion. */ |
| 818 | XSETINT (temp, nbytes + Z); | 1015 | XSETINT (temp, outgoing_nbytes + Z); |
| 819 | if (nbytes + Z != XINT (temp)) | 1016 | if (outgoing_nbytes + Z != XINT (temp)) |
| 820 | error ("Maximum buffer size exceeded"); | 1017 | error ("Maximum buffer size exceeded"); |
| 821 | 1018 | ||
| 822 | prepare_to_modify_buffer (PT, PT, NULL); | 1019 | prepare_to_modify_buffer (PT, PT, NULL); |
| 823 | 1020 | ||
| 824 | if (PT != GPT) | 1021 | if (PT != GPT) |
| 825 | move_gap_both (PT, PT_BYTE); | 1022 | move_gap_both (PT, PT_BYTE); |
| 826 | if (GAP_SIZE < nbytes) | 1023 | if (GAP_SIZE < outgoing_nbytes) |
| 827 | make_gap (nbytes - GAP_SIZE); | 1024 | make_gap (outgoing_nbytes - GAP_SIZE); |
| 828 | 1025 | ||
| 829 | record_insert (PT, nchars); | 1026 | record_insert (PT, nchars); |
| 830 | MODIFF++; | 1027 | MODIFF++; |
| @@ -832,32 +1029,38 @@ insert_from_buffer_1 (buf, from, nchars, inherit) | |||
| 832 | if (from < BUF_GPT (buf)) | 1029 | if (from < BUF_GPT (buf)) |
| 833 | { | 1030 | { |
| 834 | chunk = BUF_GPT_BYTE (buf) - from_byte; | 1031 | chunk = BUF_GPT_BYTE (buf) - from_byte; |
| 835 | if (chunk > nbytes) | 1032 | if (chunk > incoming_nbytes) |
| 836 | chunk = nbytes; | 1033 | chunk = incoming_nbytes; |
| 837 | bcopy (BUF_BYTE_ADDRESS (buf, from_byte), GPT_ADDR, chunk); | 1034 | copy_text (BUF_BYTE_ADDRESS (buf, from_byte), |
| 1035 | GPT_ADDR, chunk, | ||
| 1036 | ! NILP (buf->enable_multibyte_characters), | ||
| 1037 | ! NILP (current_buffer->enable_multibyte_characters)); | ||
| 838 | } | 1038 | } |
| 839 | else | 1039 | else |
| 840 | chunk = 0; | 1040 | chunk = 0; |
| 841 | if (chunk < nbytes) | 1041 | if (chunk < incoming_nbytes) |
| 842 | bcopy (BUF_BYTE_ADDRESS (buf, from_byte + chunk), | 1042 | copy_text (BUF_BYTE_ADDRESS (buf, from_byte + chunk), |
| 843 | GPT_ADDR + chunk, nbytes - chunk); | 1043 | GPT_ADDR + chunk, incoming_nbytes - chunk, |
| 1044 | ! NILP (buf->enable_multibyte_characters), | ||
| 1045 | ! NILP (current_buffer->enable_multibyte_characters)); | ||
| 844 | 1046 | ||
| 845 | #ifdef USE_TEXT_PROPERTIES | 1047 | #ifdef USE_TEXT_PROPERTIES |
| 846 | if (BUF_INTERVALS (current_buffer) != 0) | 1048 | if (BUF_INTERVALS (current_buffer) != 0) |
| 847 | offset_intervals (current_buffer, PT, nchars); | 1049 | offset_intervals (current_buffer, PT, nchars); |
| 848 | #endif | 1050 | #endif |
| 849 | 1051 | ||
| 850 | GAP_SIZE -= nbytes; | 1052 | GAP_SIZE -= outgoing_nbytes; |
| 851 | GPT += nchars; | 1053 | GPT += nchars; |
| 852 | ZV += nchars; | 1054 | ZV += nchars; |
| 853 | Z += nchars; | 1055 | Z += nchars; |
| 854 | GPT_BYTE += nbytes; | 1056 | GPT_BYTE += outgoing_nbytes; |
| 855 | ZV_BYTE += nbytes; | 1057 | ZV_BYTE += outgoing_nbytes; |
| 856 | Z_BYTE += nbytes; | 1058 | Z_BYTE += outgoing_nbytes; |
| 857 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ | 1059 | if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ |
| 858 | adjust_overlays_for_insert (PT, nchars); | 1060 | adjust_overlays_for_insert (PT, nchars); |
| 859 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, PT_BYTE + nbytes, 0); | 1061 | adjust_markers_for_insert (PT, PT_BYTE, PT + nchars, |
| 860 | adjust_point (nchars, nbytes); | 1062 | PT_BYTE + outgoing_nbytes, 0); |
| 1063 | adjust_point (nchars, outgoing_nbytes); | ||
| 861 | 1064 | ||
| 862 | if (GPT_BYTE < GPT) | 1065 | if (GPT_BYTE < GPT) |
| 863 | abort (); | 1066 | abort (); |
| @@ -884,8 +1087,8 @@ replace_range (from, to, new, prepare, inherit) | |||
| 884 | Lisp_Object new; | 1087 | Lisp_Object new; |
| 885 | int from, to, prepare, inherit; | 1088 | int from, to, prepare, inherit; |
| 886 | { | 1089 | { |
| 887 | int insbytes = XSTRING (new)->size; | 1090 | int inschars = XSTRING (new)->size; |
| 888 | int inschars; | 1091 | int insbytes = XSTRING (new)->size_byte; |
| 889 | int from_byte, to_byte; | 1092 | int from_byte, to_byte; |
| 890 | int nbytes_del, nchars_del; | 1093 | int nbytes_del, nchars_del; |
| 891 | register Lisp_Object temp; | 1094 | register Lisp_Object temp; |
| @@ -922,8 +1125,6 @@ replace_range (from, to, new, prepare, inherit) | |||
| 922 | if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) | 1125 | if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) |
| 923 | error ("Maximum buffer size exceeded"); | 1126 | error ("Maximum buffer size exceeded"); |
| 924 | 1127 | ||
| 925 | inschars = XINT (Fchars_in_string (new)); | ||
| 926 | |||
| 927 | GCPRO1 (new); | 1128 | GCPRO1 (new); |
| 928 | 1129 | ||
| 929 | /* Make sure the gap is somewhere in or next to what we are deleting. */ | 1130 | /* Make sure the gap is somewhere in or next to what we are deleting. */ |