aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard M. Stallman1998-03-11 22:08:24 +0000
committerRichard M. Stallman1998-03-11 22:08:24 +0000
commit1f90a790f50b7c848f97a0c0b9d95a045826e033 (patch)
tree6a0bd7ee042bdd893ac488e0163ca4e57048604e
parentce97a2d7ed0eb52e291522ecdc23029c6002c839 (diff)
downloademacs-1f90a790f50b7c848f97a0c0b9d95a045826e033.tar.gz
emacs-1f90a790f50b7c848f97a0c0b9d95a045826e033.zip
(combine_bytes): New function.
(insert_1_both, insert_from_string_1, insert_from_buffer_1): Simplify greatly by using combine_bytes near the end to handle all aspects of combining except for undo-recording. This means most of the code deals with the text as if there were no combining. (replace_range): Likewise. Also handle unibyte-multibyte conversion as in insert_from_string_1. (del_range_2): Handle combining of character before the deletion with strays after the deletion. (adjust_markers_for_delete): Delete debugging code for Z == Z_BYTE. (adjust_markers_for_insert): Move Z == Z_BYTE debugging code to before we relocate the marker.
-rw-r--r--src/insdel.c382
1 files changed, 208 insertions, 174 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 1e787e24fdb..6eff006cb6c 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -368,24 +368,6 @@ adjust_markers_for_delete (from, from_byte, to, to_byte)
368 m->bytepos = from_byte; 368 m->bytepos = from_byte;
369 } 369 }
370 370
371 /* In a single-byte buffer, a marker's two positions must be equal. */
372 if (Z == Z_BYTE)
373 {
374 register int i = m->bytepos;
375
376#if 0
377 /* We use FROM_BYTE here instead of GPT_BYTE
378 because FROM_BYTE is where the gap will be after the deletion. */
379 if (i > from_byte + coming_gap_size)
380 i -= coming_gap_size;
381 else if (i > from_byte)
382 i = from_byte;
383#endif
384
385 if (m->charpos != i)
386 abort ();
387 }
388
389 marker = m->chain; 371 marker = m->chain;
390 } 372 }
391} 373}
@@ -420,6 +402,17 @@ adjust_markers_for_insert (from, from_byte, to, to_byte,
420 while (!NILP (marker)) 402 while (!NILP (marker))
421 { 403 {
422 register struct Lisp_Marker *m = XMARKER (marker); 404 register struct Lisp_Marker *m = XMARKER (marker);
405
406 /* In a single-byte buffer, a marker's two positions must be equal.
407 (If this insertion is going to combine characters, Z will
408 become different from Z_BYTE, but they might be the same now.
409 If so, the two OLD positions of the marker should be equal.) */
410 if (Z == Z_BYTE)
411 {
412 if (m->charpos != m->bytepos)
413 abort ();
414 }
415
423 if (m->bytepos == from_byte) 416 if (m->bytepos == from_byte)
424 { 417 {
425 if (m->insertion_type || before_markers) 418 if (m->insertion_type || before_markers)
@@ -465,13 +458,6 @@ adjust_markers_for_insert (from, from_byte, to, to_byte,
465 m->charpos += nchars; 458 m->charpos += nchars;
466 } 459 }
467 460
468 /* In a single-byte buffer, a marker's two positions must be equal. */
469 if (Z == Z_BYTE)
470 {
471 if (m->charpos != m->bytepos)
472 abort ();
473 }
474
475 marker = m->chain; 461 marker = m->chain;
476 } 462 }
477 463
@@ -762,7 +748,7 @@ insert_before_markers_and_inherit (string, nbytes)
762 signal_after_change (opoint, 0, PT - opoint); 748 signal_after_change (opoint, 0, PT - opoint);
763 } 749 }
764} 750}
765 751
766/* Subroutine used by the insert functions above. */ 752/* Subroutine used by the insert functions above. */
767 753
768void 754void
@@ -774,7 +760,7 @@ insert_1 (string, nbytes, inherit, prepare, before_markers)
774 insert_1_both (string, chars_in_text (string, nbytes), nbytes, 760 insert_1_both (string, chars_in_text (string, nbytes), nbytes,
775 inherit, prepare, before_markers); 761 inherit, prepare, before_markers);
776} 762}
777 763
778/* See if the bytes before POS/POS_BYTE combine with bytes 764/* See if the bytes before POS/POS_BYTE combine with bytes
779 at the start of STRING to form a single character. 765 at the start of STRING to form a single character.
780 If so, return the number of bytes at the start of STRING 766 If so, return the number of bytes at the start of STRING
@@ -855,6 +841,34 @@ count_combining_after (string, length, pos, pos_byte)
855 return pos_byte - opos_byte; 841 return pos_byte - opos_byte;
856} 842}
857 843
844/* Combine NBYTES stray trailing-codes, which were formerly separate
845 characters, with the preceding character. These bytes
846 are located after position POS / POS_BYTE, and the preceding character
847 is located just before that position. */
848
849static void
850combine_bytes (pos, pos_byte, nbytes)
851 int pos, pos_byte, nbytes;
852{
853 /* Adjust all markers. */
854 adjust_markers_for_delete (pos, pos_byte, pos + nbytes, pos_byte);
855
856 adjust_overlays_for_delete (pos, nbytes);
857
858 if (PT > pos)
859 BUF_PT (current_buffer) -= nbytes;
860 if (GPT > pos)
861 GPT -= nbytes;
862 if (Z > pos)
863 Z -= nbytes;
864 if (ZV > pos)
865 ZV -= nbytes;
866
867 if (BUF_INTERVALS (current_buffer) != 0)
868 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
869 offset_intervals (current_buffer, pos, - nbytes);
870}
871
858/* Insert a sequence of NCHARS chars which occupy NBYTES bytes 872/* Insert a sequence of NCHARS chars which occupy NBYTES bytes
859 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS 873 starting at STRING. INHERIT, PREPARE and BEFORE_MARKERS
860 are the same as in insert_1. */ 874 are the same as in insert_1. */
@@ -867,7 +881,6 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
867{ 881{
868 register Lisp_Object temp; 882 register Lisp_Object temp;
869 int combined_before_bytes, combined_after_bytes; 883 int combined_before_bytes, combined_after_bytes;
870 int adjusted_nchars;
871 884
872 if (NILP (current_buffer->enable_multibyte_characters)) 885 if (NILP (current_buffer->enable_multibyte_characters))
873 nchars = nbytes; 886 nchars = nbytes;
@@ -877,17 +890,13 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
877 if (GAP_SIZE < nbytes) 890 if (GAP_SIZE < nbytes)
878 make_gap (nbytes - GAP_SIZE); 891 make_gap (nbytes - GAP_SIZE);
879 892
880 combined_before_bytes = count_combining_before (string, nbytes, PT, PT_BYTE);
881 combined_after_bytes = count_combining_after (string, nbytes, PT, PT_BYTE);
882
883 /* This is the net amount that Z will increase from this insertion. */
884
885 adjusted_nchars = nchars - combined_before_bytes - combined_after_bytes;
886
887 if (prepare) 893 if (prepare)
888 prepare_to_modify_buffer (PT - !!combined_before_bytes, 894 prepare_to_modify_buffer (PT, PT, NULL);
889 PT + combined_after_bytes, 895
890 NULL); 896 combined_before_bytes
897 = count_combining_before (string, nbytes, PT, PT_BYTE);
898 combined_after_bytes
899 = count_combining_after (string, nbytes, PT, PT_BYTE);
891 900
892 /* Record deletion of the surrounding text that combines with 901 /* Record deletion of the surrounding text that combines with
893 the insertion. This, together with recording the insertion, 902 the insertion. This, together with recording the insertion,
@@ -907,49 +916,52 @@ insert_1_both (string, nchars, nbytes, inherit, prepare, before_markers)
907 916
908 bcopy (string, GPT_ADDR, nbytes); 917 bcopy (string, GPT_ADDR, nbytes);
909 918
910#ifdef USE_TEXT_PROPERTIES
911 if (BUF_INTERVALS (current_buffer) != 0)
912 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
913 offset_intervals (current_buffer, PT, adjusted_nchars);
914#endif
915
916 GAP_SIZE -= nbytes; 919 GAP_SIZE -= nbytes;
917 /* When we have combining at the end of the insertion, 920 /* When we have combining at the end of the insertion,
918 this is the character position before the combined character. */ 921 this is the character position before the combined character. */
919 GPT += nchars - combined_before_bytes - !!combined_after_bytes; 922 GPT += nchars;
920 ZV += adjusted_nchars; 923 ZV += nchars;
921 Z += adjusted_nchars; 924 Z += nchars;
922 GPT_BYTE += nbytes; 925 GPT_BYTE += nbytes;
923 ZV_BYTE += nbytes; 926 ZV_BYTE += nbytes;
924 Z_BYTE += nbytes; 927 Z_BYTE += nbytes;
925 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ 928 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
926 adjust_overlays_for_insert (PT, adjusted_nchars); 929
930 if (combined_after_bytes)
931 move_gap_both (GPT + combined_after_bytes,
932 GPT_BYTE + combined_after_bytes);
933
934 if (GPT_BYTE < GPT)
935 abort ();
936
937 adjust_overlays_for_insert (PT, nchars);
927 adjust_markers_for_insert (PT, PT_BYTE, 938 adjust_markers_for_insert (PT, PT_BYTE,
928 PT + adjusted_nchars, PT_BYTE + nbytes, 939 PT + nchars, PT_BYTE + nbytes,
929 combined_before_bytes, combined_after_bytes, 940 combined_before_bytes, combined_after_bytes,
930 before_markers); 941 before_markers);
931 942
932 /* "Delete" the combined-after bytes, as far as intervals are concerned.
933 Note that as far as the intervals are concerned,
934 no insertion has yet taken place, so these bytes are right after PT. */
935 if (combined_after_bytes)
936 offset_intervals (current_buffer, PT, - combined_after_bytes);
937
938#ifdef USE_TEXT_PROPERTIES 943#ifdef USE_TEXT_PROPERTIES
944 if (BUF_INTERVALS (current_buffer) != 0)
945 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES. */
946 offset_intervals (current_buffer, PT, nchars);
947
939 if (!inherit && BUF_INTERVALS (current_buffer) != 0) 948 if (!inherit && BUF_INTERVALS (current_buffer) != 0)
940 Fset_text_properties (make_number (PT), 949 Fset_text_properties (make_number (PT), make_number (PT + nchars),
941 make_number (PT + adjusted_nchars + combined_after_bytes),
942 Qnil, Qnil); 950 Qnil, Qnil);
943#endif 951#endif
944 952
945 adjust_point (adjusted_nchars + combined_after_bytes, 953 {
946 nbytes + combined_after_bytes); 954 int pos = PT, pos_byte = PT_BYTE;
947 955
948 if (combined_after_bytes) 956 adjust_point (nchars + combined_after_bytes,
949 move_gap_both (GPT + 1, GPT_BYTE + combined_after_bytes); 957 nbytes + combined_after_bytes);
950 958
951 if (GPT_BYTE < GPT) 959 if (combined_after_bytes)
952 abort (); 960 combine_bytes (pos + nchars, pos_byte + nbytes, combined_after_bytes);
961
962 if (combined_before_bytes)
963 combine_bytes (pos, pos_byte, combined_before_bytes);
964 }
953} 965}
954 966
955/* Insert the part of the text of STRING, a Lisp object assumed to be 967/* Insert the part of the text of STRING, a Lisp object assumed to be
@@ -1052,14 +1064,9 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1052 the text that has been stored by copy_text. */ 1064 the text that has been stored by copy_text. */
1053 1065
1054 combined_before_bytes 1066 combined_before_bytes
1055 = count_combining_before (XSTRING (string)->data + pos_byte, nbytes, 1067 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1056 PT, PT_BYTE);
1057 combined_after_bytes 1068 combined_after_bytes
1058 = count_combining_after (XSTRING (string)->data + pos_byte, nbytes, 1069 = count_combining_after (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1059 PT, PT_BYTE);
1060
1061 /* This is the net amount that Z will increase from this insertion. */
1062 adjusted_nchars = nchars - combined_before_bytes - combined_after_bytes;
1063 1070
1064 /* Record deletion of the surrounding text that combines with 1071 /* Record deletion of the surrounding text that combines with
1065 the insertion. This, together with recording the insertion, 1072 the insertion. This, together with recording the insertion,
@@ -1077,49 +1084,54 @@ insert_from_string_1 (string, pos, pos_byte, nchars, nbytes,
1077 record_insert (PT - !!combined_before_bytes, nchars); 1084 record_insert (PT - !!combined_before_bytes, nchars);
1078 MODIFF++; 1085 MODIFF++;
1079 1086
1080 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1081 offset_intervals (current_buffer, PT, adjusted_nchars);
1082
1083 GAP_SIZE -= outgoing_nbytes; 1087 GAP_SIZE -= outgoing_nbytes;
1084 GPT += nchars - combined_before_bytes - !!combined_after_bytes; 1088 GPT += nchars;
1085 ZV += adjusted_nchars; 1089 ZV += nchars;
1086 Z += adjusted_nchars; 1090 Z += nchars;
1087 GPT_BYTE += outgoing_nbytes; 1091 GPT_BYTE += outgoing_nbytes;
1088 ZV_BYTE += outgoing_nbytes; 1092 ZV_BYTE += outgoing_nbytes;
1089 Z_BYTE += outgoing_nbytes; 1093 Z_BYTE += outgoing_nbytes;
1090 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ 1094 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1091 adjust_overlays_for_insert (PT, adjusted_nchars);
1092 adjust_markers_for_insert (PT, PT_BYTE, PT + adjusted_nchars,
1093 PT_BYTE + outgoing_nbytes,
1094 combined_before_bytes, combined_after_bytes,
1095 before_markers);
1096 1095
1097 if (combined_after_bytes) 1096 if (combined_after_bytes)
1098 move_gap_both (GPT + 1, GPT_BYTE + combined_after_bytes); 1097 move_gap_both (GPT + combined_after_bytes,
1098 GPT_BYTE + combined_after_bytes);
1099 1099
1100 if (GPT_BYTE < GPT) 1100 if (GPT_BYTE < GPT)
1101 abort (); 1101 abort ();
1102 1102
1103 /* "Delete" the combined-after bytes, as far as intervals are concerned. 1103 adjust_overlays_for_insert (PT, nchars);
1104 Note that as far as the intervals are concerned, 1104 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1105 no insertion has yet taken place, so these bytes are right after PT. */ 1105 PT_BYTE + outgoing_nbytes,
1106 if (combined_after_bytes) 1106 combined_before_bytes, combined_after_bytes,
1107 offset_intervals (current_buffer, PT, - combined_after_bytes); 1107 before_markers);
1108 1108
1109 /* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
1110 offset_intervals (current_buffer, PT, nchars);
1111
1112 intervals = XSTRING (string)->intervals;
1109 /* Get the intervals for the part of the string we are inserting-- 1113 /* Get the intervals for the part of the string we are inserting--
1110 not including the combined-before bytes. */ 1114 not including the combined-before bytes. */
1111 intervals = XSTRING (string)->intervals; 1115 if (nbytes < XSTRING (string)->size_byte)
1112 if (combined_before_bytes != 0 1116 intervals = copy_intervals (intervals, pos, nchars);
1113 || nbytes < XSTRING (string)->size_byte)
1114 intervals = copy_intervals (intervals, pos + combined_before_bytes,
1115 nchars - combined_before_bytes);
1116 1117
1117 /* Insert those intervals. */ 1118 /* Insert those intervals. */
1118 graft_intervals_into_buffer (intervals, PT, nchars - combined_before_bytes, 1119 graft_intervals_into_buffer (intervals, PT, nchars,
1119 current_buffer, inherit); 1120 current_buffer, inherit);
1120 1121
1121 adjust_point (adjusted_nchars + combined_after_bytes, 1122 {
1122 outgoing_nbytes + combined_after_bytes); 1123 int pos = PT, pos_byte = PT_BYTE;
1124
1125 adjust_point (nchars + combined_after_bytes,
1126 outgoing_nbytes + combined_after_bytes);
1127
1128 if (combined_after_bytes)
1129 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1130 combined_after_bytes);
1131
1132 if (combined_before_bytes)
1133 combine_bytes (pos, pos_byte, combined_before_bytes);
1134 }
1123} 1135}
1124 1136
1125/* Insert text from BUF, NCHARS characters starting at CHARPOS, into the 1137/* Insert text from BUF, NCHARS characters starting at CHARPOS, into the
@@ -1203,17 +1215,14 @@ insert_from_buffer_1 (buf, from, nchars, inherit)
1203 /* We have copied text into the gap, but we have not altered 1215 /* We have copied text into the gap, but we have not altered
1204 PT or PT_BYTE yet. So we can pass PT and PT_BYTE 1216 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1205 to these functions and get the same results as we would 1217 to these functions and get the same results as we would
1206 have got earlier on. Meanwhile, PT_ADDR does point to 1218 have got earlier on. Meanwhile, GPT_ADDR does point to
1207 the text that has been stored by copy_text. */ 1219 the text that has been stored by copy_text. */
1208 combined_before_bytes 1220 combined_before_bytes
1209 = count_combining_before (PT_ADDR, outgoing_nbytes, PT, PT_BYTE); 1221 = count_combining_before (GPT_ADDR, outgoing_nbytes, PT, PT_BYTE);
1210 combined_after_bytes 1222 combined_after_bytes
1211 = count_combining_after (PT_ADDR, outgoing_nbytes, 1223 = count_combining_after (GPT_ADDR, outgoing_nbytes,
1212 PT, PT_BYTE); 1224 PT, PT_BYTE);
1213 1225
1214 /* This is the net amount that Z will increase from this insertion. */
1215 adjusted_nchars = nchars - combined_before_bytes - combined_after_bytes;
1216
1217 /* Record deletion of the surrounding text that combines with 1226 /* Record deletion of the surrounding text that combines with
1218 the insertion. This, together with recording the insertion, 1227 the insertion. This, together with recording the insertion,
1219 will add up to the right stuff in the undo list. 1228 will add up to the right stuff in the undo list.
@@ -1230,51 +1239,54 @@ insert_from_buffer_1 (buf, from, nchars, inherit)
1230 record_insert (PT - !!combined_before_bytes, nchars); 1239 record_insert (PT - !!combined_before_bytes, nchars);
1231 MODIFF++; 1240 MODIFF++;
1232 1241
1233#ifdef USE_TEXT_PROPERTIES
1234 if (BUF_INTERVALS (current_buffer) != 0)
1235 offset_intervals (current_buffer, PT, adjusted_nchars);
1236#endif
1237
1238 GAP_SIZE -= outgoing_nbytes; 1242 GAP_SIZE -= outgoing_nbytes;
1239 GPT += nchars - combined_before_bytes - !!combined_after_bytes; 1243 GPT += nchars;
1240 ZV += adjusted_nchars; 1244 ZV += nchars;
1241 Z += adjusted_nchars; 1245 Z += nchars;
1242 GPT_BYTE += outgoing_nbytes; 1246 GPT_BYTE += outgoing_nbytes;
1243 ZV_BYTE += outgoing_nbytes; 1247 ZV_BYTE += outgoing_nbytes;
1244 Z_BYTE += outgoing_nbytes; 1248 Z_BYTE += outgoing_nbytes;
1245 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ 1249 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1246 adjust_overlays_for_insert (PT, adjusted_nchars); 1250
1247 adjust_markers_for_insert (PT, PT_BYTE, PT + adjusted_nchars, 1251 if (combined_after_bytes)
1252 move_gap_both (GPT + combined_after_bytes,
1253 GPT_BYTE + combined_after_bytes);
1254
1255 if (GPT_BYTE < GPT)
1256 abort ();
1257
1258 adjust_overlays_for_insert (PT, nchars);
1259 adjust_markers_for_insert (PT, PT_BYTE, PT + nchars,
1248 PT_BYTE + outgoing_nbytes, 1260 PT_BYTE + outgoing_nbytes,
1249 combined_before_bytes, combined_after_bytes, 0); 1261 combined_before_bytes, combined_after_bytes, 0);
1250 1262
1251 /* "Delete" the combined-after bytes, as far as intervals are concerned. 1263#ifdef USE_TEXT_PROPERTIES
1252 Note that as far as the intervals are concerned, 1264 if (BUF_INTERVALS (current_buffer) != 0)
1253 no insertion has yet taken place, so these bytes are right after PT. */ 1265 offset_intervals (current_buffer, PT, nchars);
1254 if (combined_after_bytes) 1266#endif
1255 offset_intervals (current_buffer, PT, - combined_after_bytes);
1256 1267
1257 /* Get the intervals for the part of the string we are inserting-- 1268 /* Get the intervals for the part of the string we are inserting--
1258 not including the combined-before bytes. */ 1269 not including the combined-before bytes. */
1259 intervals = BUF_INTERVALS (buf); 1270 intervals = BUF_INTERVALS (buf);
1260 if (combined_before_bytes != 0 1271 if (outgoing_nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf))
1261 || nbytes < BUF_Z_BYTE (buf) - BUF_BEG_BYTE (buf)) 1272 intervals = copy_intervals (intervals, from, nchars);
1262 intervals = copy_intervals (intervals, from + combined_before_bytes,
1263 nchars - combined_before_bytes);
1264 1273
1265 /* Insert those intervals. */ 1274 /* Insert those intervals. */
1266 graft_intervals_into_buffer (intervals, PT, nchars - combined_before_bytes, 1275 graft_intervals_into_buffer (intervals, PT, nchars, current_buffer, inherit);
1267 current_buffer, inherit);
1268 1276
1277 {
1278 int pos = PT, pos_byte = PT_BYTE;
1269 1279
1270 adjust_point (adjusted_nchars + combined_after_bytes, 1280 adjust_point (nchars + combined_after_bytes,
1271 outgoing_nbytes + combined_after_bytes); 1281 outgoing_nbytes + combined_after_bytes);
1272 1282
1273 if (combined_after_bytes) 1283 if (combined_after_bytes)
1274 move_gap_both (GPT + 1, GPT_BYTE + combined_after_bytes); 1284 combine_bytes (pos + nchars, pos_byte + outgoing_nbytes,
1285 combined_after_bytes);
1275 1286
1276 if (GPT_BYTE < GPT) 1287 if (combined_before_bytes)
1277 abort (); 1288 combine_bytes (pos, pos_byte, combined_before_bytes);
1289 }
1278} 1290}
1279 1291
1280/* This function should be called after moving gap to FROM and before 1292/* This function should be called after moving gap to FROM and before
@@ -1344,6 +1356,7 @@ replace_range (from, to, new, prepare, inherit)
1344 int combined_before_bytes, combined_after_bytes; 1356 int combined_before_bytes, combined_after_bytes;
1345 int adjusted_inschars; 1357 int adjusted_inschars;
1346 INTERVAL intervals; 1358 INTERVAL intervals;
1359 int outgoing_insbytes = insbytes;
1347 1360
1348 GCPRO1 (new); 1361 GCPRO1 (new);
1349 1362
@@ -1371,6 +1384,15 @@ replace_range (from, to, new, prepare, inherit)
1371 if (nbytes_del <= 0 && insbytes == 0) 1384 if (nbytes_del <= 0 && insbytes == 0)
1372 return; 1385 return;
1373 1386
1387 /* Make OUTGOING_INSBYTES describe the text
1388 as it will be inserted in this buffer. */
1389
1390 if (NILP (current_buffer->enable_multibyte_characters))
1391 outgoing_insbytes = inschars;
1392 else if (inschars == insbytes)
1393 outgoing_insbytes
1394 = count_size_as_multibyte (XSTRING (new)->data, insbytes);
1395
1374 /* Make sure point-max won't overflow after this insertion. */ 1396 /* Make sure point-max won't overflow after this insertion. */
1375 XSETINT (temp, Z_BYTE - nbytes_del + insbytes); 1397 XSETINT (temp, Z_BYTE - nbytes_del + insbytes);
1376 if (Z_BYTE - nbytes_del + insbytes != XINT (temp)) 1398 if (Z_BYTE - nbytes_del + insbytes != XINT (temp))
@@ -1412,20 +1434,26 @@ replace_range (from, to, new, prepare, inherit)
1412 if (GAP_SIZE < insbytes) 1434 if (GAP_SIZE < insbytes)
1413 make_gap (insbytes - GAP_SIZE); 1435 make_gap (insbytes - GAP_SIZE);
1414 1436
1437 /* Copy the string text into the buffer, perhaps converting
1438 between single-byte and multibyte. */
1439 copy_text (XSTRING (new)->data, GPT_ADDR, insbytes,
1440 /* If these are equal, it is a single-byte string.
1441 Its chars are either ASCII, in which case copy_text
1442 won't change it, or single-byte non-ASCII chars,
1443 that need to be changed. */
1444 inschars != insbytes,
1445 ! NILP (current_buffer->enable_multibyte_characters));
1446
1415 /* We have copied text into the gap, but we have not altered 1447 /* We have copied text into the gap, but we have not altered
1416 PT or PT_BYTE yet. So we can pass PT and PT_BYTE 1448 PT or PT_BYTE yet. So we can pass PT and PT_BYTE
1417 to these functions and get the same results as we would 1449 to these functions and get the same results as we would
1418 have got earlier on. Meanwhile, PT_ADDR does point to 1450 have got earlier on. Meanwhile, GPT_ADDR does point to
1419 the text that has been stored by copy_text. */ 1451 the text that has been stored by copy_text. */
1420 1452
1421 combined_before_bytes 1453 combined_before_bytes
1422 = count_combining_before (XSTRING (new)->data, insbytes, PT, PT_BYTE); 1454 = count_combining_before (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1423 combined_after_bytes 1455 combined_after_bytes
1424 = count_combining_after (XSTRING (new)->data, insbytes, PT, PT_BYTE); 1456 = count_combining_after (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
1425
1426 /* This is the net amount that Z will increase from this insertion. */
1427 adjusted_inschars
1428 = inschars - combined_before_bytes - combined_after_bytes;
1429 1457
1430 /* Record deletion of the surrounding text that combines with 1458 /* Record deletion of the surrounding text that combines with
1431 the insertion. This, together with recording the insertion, 1459 the insertion. This, together with recording the insertion,
@@ -1442,68 +1470,63 @@ replace_range (from, to, new, prepare, inherit)
1442 1470
1443 record_insert (from, inschars); 1471 record_insert (from, inschars);
1444 1472
1445 bcopy (XSTRING (new)->data, GPT_ADDR, insbytes); 1473 GAP_SIZE -= outgoing_insbytes;
1446 1474 GPT += inschars;
1447 /* Relocate point as if it were a marker. */ 1475 ZV += inschars;
1448 if (from < PT) 1476 Z += inschars;
1449 adjust_point ((from + adjusted_inschars - (PT < to ? PT : to) 1477 GPT_BYTE += outgoing_insbytes;
1450 + combined_after_bytes), 1478 ZV_BYTE += outgoing_insbytes;
1451 (from_byte + insbytes 1479 Z_BYTE += outgoing_insbytes;
1452 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)
1453 + combined_after_bytes));
1454
1455#ifdef USE_TEXT_PROPERTIES
1456 offset_intervals (current_buffer, PT, adjusted_inschars - nchars_del);
1457#endif
1458
1459 GAP_SIZE -= insbytes;
1460 GPT += inschars - combined_before_bytes - !!combined_after_bytes;
1461 ZV += adjusted_inschars;
1462 Z += adjusted_inschars;
1463 GPT_BYTE += insbytes;
1464 ZV_BYTE += insbytes;
1465 ZV_BYTE += insbytes;
1466 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */ 1480 if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
1467 1481
1482 if (combined_after_bytes)
1483 move_gap_both (GPT + combined_after_bytes,
1484 GPT_BYTE + combined_after_bytes);
1485
1468 if (GPT_BYTE < GPT) 1486 if (GPT_BYTE < GPT)
1469 abort (); 1487 abort ();
1470 1488
1471 /* Adjust the overlay center as needed. This must be done after 1489 /* Adjust the overlay center as needed. This must be done after
1472 adjusting the markers that bound the overlays. */ 1490 adjusting the markers that bound the overlays. */
1473 adjust_overlays_for_delete (from, nchars_del); 1491 adjust_overlays_for_delete (from, nchars_del);
1474 adjust_overlays_for_insert (from, adjusted_inschars); 1492 adjust_overlays_for_insert (from, inschars);
1475 adjust_markers_for_insert (from, from_byte, from + adjusted_inschars, 1493 adjust_markers_for_insert (from, from_byte,
1476 from_byte + insbytes, 1494 from + inschars, from_byte + outgoing_insbytes,
1477 combined_before_bytes, combined_after_bytes, 0); 1495 combined_before_bytes, combined_after_bytes, 0);
1478 1496
1479 /* "Delete" the combined-after bytes, as far as intervals are concerned. 1497#ifdef USE_TEXT_PROPERTIES
1480 Note that as far as the intervals are concerned, 1498 offset_intervals (current_buffer, PT, inschars - nchars_del);
1481 no insertion has yet taken place, so these bytes are right after PT. */
1482 if (combined_after_bytes)
1483 offset_intervals (current_buffer, PT, - combined_after_bytes);
1484 1499
1485 /* Get the intervals for the part of the string we are inserting-- 1500 /* Get the intervals for the part of the string we are inserting--
1486 not including the combined-before bytes. */ 1501 not including the combined-before bytes. */
1487 intervals = XSTRING (new)->intervals; 1502 intervals = XSTRING (new)->intervals;
1488 if (combined_before_bytes != 0)
1489 intervals = copy_intervals (intervals, combined_before_bytes,
1490 inschars - combined_before_bytes);
1491
1492 /* Insert those intervals. */ 1503 /* Insert those intervals. */
1493 graft_intervals_into_buffer (intervals, from, 1504 graft_intervals_into_buffer (intervals, from, inschars,
1494 inschars - combined_before_bytes,
1495 current_buffer, inherit); 1505 current_buffer, inherit);
1506#endif
1496 1507
1497 if (insbytes == 0) 1508 /* Relocate point as if it were a marker. */
1498 evaporate_overlays (from); 1509 if (from < PT)
1510 adjust_point ((from + inschars - (PT < to ? PT : to)
1511 + combined_after_bytes),
1512 (from_byte + outgoing_insbytes
1513 - (PT_BYTE < to_byte ? PT_BYTE : to_byte)
1514 + combined_after_bytes));
1499 1515
1500 if (combined_after_bytes) 1516 if (combined_after_bytes)
1501 move_gap_both (GPT + 1, GPT_BYTE + combined_after_bytes); 1517 combine_bytes (from + inschars, from_byte + outgoing_insbytes,
1518 combined_after_bytes);
1519
1520 if (combined_before_bytes)
1521 combine_bytes (from, from_byte, combined_before_bytes);
1522
1523 if (outgoing_insbytes == 0)
1524 evaporate_overlays (from);
1502 1525
1503 MODIFF++; 1526 MODIFF++;
1504 UNGCPRO; 1527 UNGCPRO;
1505 1528
1506 signal_after_change (from, nchars_del, adjusted_inschars); 1529 signal_after_change (from, nchars_del, PT - from);
1507} 1530}
1508 1531
1509/* Delete characters in current buffer 1532/* Delete characters in current buffer
@@ -1629,6 +1652,7 @@ del_range_2 (from, from_byte, to, to_byte)
1629 int from, from_byte, to, to_byte; 1652 int from, from_byte, to, to_byte;
1630{ 1653{
1631 register int nbytes_del, nchars_del; 1654 register int nbytes_del, nchars_del;
1655 int combined_after_bytes;
1632 1656
1633 nchars_del = to - from; 1657 nchars_del = to - from;
1634 nbytes_del = to_byte - from_byte; 1658 nbytes_del = to_byte - from_byte;
@@ -1677,6 +1701,16 @@ del_range_2 (from, from_byte, to, to_byte)
1677 if (Z - GPT < end_unchanged) 1701 if (Z - GPT < end_unchanged)
1678 end_unchanged = Z - GPT; 1702 end_unchanged = Z - GPT;
1679 1703
1704 combined_after_bytes
1705 = count_combining_before (GAP_END_ADDR, ZV_BYTE - GPT_BYTE, PT, PT_BYTE);
1706
1707 if (combined_after_bytes)
1708 move_gap_both (GPT + combined_after_bytes,
1709 GPT_BYTE + combined_after_bytes);
1710
1711 if (combined_after_bytes)
1712 combine_bytes (PT, PT_BYTE, combined_after_bytes);
1713
1680 evaporate_overlays (from); 1714 evaporate_overlays (from);
1681 signal_after_change (from, nchars_del, 0); 1715 signal_after_change (from, nchars_del, 0);
1682} 1716}