# HG changeset patch # User Kenichi Handa # Date 891237654 0 # Node ID 27b08da98abe53aebafa200f613bcf8d79d2bc34 # Parent 278c256defc66655c79f24acee66d4f50ff41b4c (code_convert_region): Handle skipped ASCII characters at the head and tail of conversion region correctly when adjusting position keepers. Call adjust_after_insert to record undo info and adjust markers when we don't have to change byte sequence of a buffer. diff -r 278c256defc6 -r 27b08da98abe src/coding.c --- a/src/coding.c Mon Mar 30 06:00:54 1998 +0000 +++ b/src/coding.c Mon Mar 30 06:00:54 1998 +0000 @@ -3950,12 +3950,13 @@ { int len = to - from, len_byte = to_byte - from_byte; int require, inserted, inserted_byte; - int from_byte_orig, to_byte_orig; + int head_skip, tail_skip, total_skip; Lisp_Object saved_coding_symbol = Qnil; int multibyte = !NILP (current_buffer->enable_multibyte_characters); int first = 1; int fake_multibyte = 0; unsigned char *src, *dst; + Lisp_Object deletion = Qnil; if (replace) { @@ -3975,10 +3976,7 @@ if (! encodep && CODING_REQUIRE_DETECTION (coding)) { - /* We must detect encoding of text and eol. Even if detection - routines can't decide the encoding, we should not let them - undecided because the deeper decoding routine (decode_coding) - tries to detect the encodings in vain in that case. */ + /* We must detect encoding of text and eol format. */ if (from < GPT && to > GPT) move_gap_both (from, from_byte); @@ -3986,6 +3984,10 @@ { detect_coding (coding, BYTE_POS_ADDR (from_byte), len_byte); if (coding->type == coding_type_undecided) + /* It seems that the text contains only ASCII, but we + should not left it undecided because the deeper + decoding routine (decode_coding) tries to detect the + encodings again in vain. */ coding->type = coding_type_emacs_mule; } if (coding->eol_type == CODING_EOL_UNDECIDED) @@ -4007,25 +4009,18 @@ : ! CODING_REQUIRE_DECODING (coding)) { coding->produced = len_byte; - if (multibyte) + if (multibyte + && ! replace + /* See the comment of the member heading_ascii in coding.h. */ + && coding->heading_ascii < len_byte) { - adjust_before_replace (from, from_byte, to, to_byte); - /* We still may have to combine byte at the head and the tail of the text in the region. */ - if (GPT != to) + if (from < GPT && GPT < to) move_gap_both (to, to_byte); - coding->produced_char - = multibyte_chars_in_text (BYTE_POS_ADDR (from_byte), len_byte); - GAP_SIZE += len_byte; - GPT_BYTE -= len_byte; - ZV_BYTE -= len_byte; - Z_BYTE -= len_byte; - GPT -= len; - ZV -= len; - Z -= len; - adjust_after_replace (from, from_byte, to, to_byte, - coding->produced_char, len_byte, replace); + len = multibyte_chars_in_text (BYTE_POS_ADDR (from_byte), len_byte); + adjust_after_insert (from, from_byte, to, to_byte, len); + coding->produced_char = len; } else coding->produced_char = len_byte; @@ -4058,26 +4053,36 @@ } } + if (replace) + deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1); + /* Try to skip the heading and tailing ASCIIs. */ - from_byte_orig = from_byte; to_byte_orig = to_byte; - if (from < GPT && GPT < to) - move_gap (from); - if (encodep) - shrink_encoding_region (&from_byte, &to_byte, coding, NULL); - else - shrink_decoding_region (&from_byte, &to_byte, coding, NULL); - if (from_byte == to_byte) - { - coding->produced = len_byte; - coding->produced_char = multibyte ? len : len_byte; - return 0; - } - - /* Here, the excluded region by shrinking contains only ASCIIs. */ - from += (from_byte - from_byte_orig); - to += (to_byte - to_byte_orig); - len = to - from; - len_byte = to_byte - from_byte; + { + int from_byte_orig = from_byte, to_byte_orig = to_byte; + + if (from < GPT && GPT < to) + move_gap_both (from, from_byte); + if (encodep) + shrink_encoding_region (&from_byte, &to_byte, coding, NULL); + else + shrink_decoding_region (&from_byte, &to_byte, coding, NULL); + if (from_byte == to_byte) + { + coding->produced = len_byte; + coding->produced_char = multibyte ? len : len_byte; + if (!replace) + /* We must record and adjust for this new text now. */ + adjust_after_insert (from, from_byte_orig, to, to_byte_orig, len); + return 0; + } + + head_skip = from_byte - from_byte_orig; + tail_skip = to_byte_orig - to_byte; + total_skip = head_skip + tail_skip; + from += head_skip; + to -= tail_skip; + len -= total_skip; len_byte -= total_skip; + } /* For converion, we must put the gap before the text in addition to making the gap larger for efficient decoding. The required gap @@ -4090,9 +4095,6 @@ make_gap (require - GAP_SIZE); move_gap_both (from, from_byte); - if (replace) - adjust_before_replace (from, from_byte, to, to_byte); - if (GPT - BEG < beg_unchanged) beg_unchanged = GPT - BEG; if (Z - GPT < end_unchanged) @@ -4238,13 +4240,25 @@ if (src - dst > 0) *dst = 0; /* Put an anchor. */ if (multibyte - && (fake_multibyte || !encodep && (to - from) != (to_byte - from_byte))) + && (fake_multibyte + || !encodep && (to - from) != (to_byte - from_byte))) inserted = multibyte_chars_in_text (GPT_ADDR, inserted_byte); - adjust_after_replace (from, from_byte, to, to_byte, - inserted, inserted_byte, replace); - if (from_byte_orig == from_byte) - from_byte_orig = from_byte = PT_BYTE; + /* If we have shrinked the conversion area, adjust it now. */ + if (total_skip > 0) + { + if (tail_skip > 0) + safe_bcopy (GAP_END_ADDR, GPT_ADDR + inserted_byte, tail_skip); + inserted += total_skip; inserted_byte += total_skip; + GAP_SIZE += total_skip; + GPT -= head_skip; GPT_BYTE -= head_skip; + ZV -= total_skip; ZV_BYTE -= total_skip; + Z -= total_skip; Z_BYTE -= total_skip; + from -= head_skip; from_byte -= head_skip; + to += tail_skip; to_byte += tail_skip; + } + + adjust_after_replace (from, from_byte, deletion, inserted, inserted_byte); if (! encodep && ! NILP (coding->post_read_conversion)) { @@ -4266,12 +4280,10 @@ signal_after_change (from, to - from, inserted); { - int skip = (to_byte_orig - to_byte) + (from_byte - from_byte_orig); - - coding->consumed = to_byte_orig - from_byte_orig; - coding->consumed_char = skip + (to - from); - coding->produced = skip + inserted_byte; - coding->produced_char = skip + inserted; + coding->consumed = to_byte - from_byte; + coding->consumed_char = to - from; + coding->produced = inserted_byte; + coding->produced_char = inserted; } return 0;