marker = m->chain;
}
}
+
+/* Adjust all markers for a byte combining of NBYTES at char position
+ FROM and byte position FROM_BYTE. */
+
+static void
+adjust_markers_for_combining (from, from_byte, nbytes)
+ register int from, from_byte, nbytes;
+{
+ Lisp_Object marker;
+ register struct Lisp_Marker *m;
+ register int bytepos;
+ register int to_byte = from_byte + nbytes;
+
+ marker = BUF_MARKERS (current_buffer);
+
+ while (!NILP (marker))
+ {
+ m = XMARKER (marker);
+ bytepos = m->bytepos;
+
+ if (bytepos >= to_byte)
+ {
+ record_marker_adjustment (marker, - nbytes);
+ m->charpos -= nbytes;
+ }
+ else if (bytepos > from_byte)
+ {
+ record_marker_adjustment (marker, from - m->charpos);
+ m->charpos = from;
+ m->bytepos = to_byte;
+ }
+ else if (bytepos == from_byte)
+ {
+ m->bytepos = to_byte;
+ }
+
+ marker = m->chain;
+ }
+}
\f
/* Adjust all markers for calling record_delete for combining bytes.
whose range in bytes is FROM_BYTE to TO_BYTE.
m->charpos = from;
m->bytepos = from_byte;
}
- else if (m->bytepos == from_byte)
- {
- if (combined_before_bytes)
- {
- DEC_BOTH (m->charpos, m->bytepos);
- INC_BOTH (m->charpos, m->bytepos);
- }
- }
marker = m->chain;
}
int thislen, c, c_save;
c = c_save = STRING_CHAR_AND_LENGTH (from_addr, bytes_left, thislen);
if (!SINGLE_BYTE_CHAR_P (c))
- {
- if (!NILP (tbl))
- {
- temp = Faref (tbl, make_number (c));
- if (INTEGERP (temp))
- c = XINT (temp);
- }
- else if (nonascii_insert_offset > 0)
- c -= nonascii_insert_offset;
- if (c < 128 || c >= 256)
- c = (c_save & 0177) + 0200;
- }
+ c = multibyte_char_to_unibyte (c, tbl);
*to_addr++ = c;
from_addr += thislen;
bytes_left -= thislen;
unsigned char workbuf[4], *str;
int len;
- if (c >= 0240 && c < 0400)
+ if ((c >= 0240 || !NILP (Vnonascii_translation_table)) && c < 0400)
{
c = unibyte_char_to_multibyte (c);
len = CHAR_STRING (c, workbuf, str);
{
unsigned int c = *ptr++;
- if (c < 0240)
+ if (c < 0240 && NILP (Vnonascii_translation_table))
outgoing_nbytes++;
else
{
c = unibyte_char_to_multibyte (c);
- outgoing_nbytes += XINT (Fchar_bytes (make_number (c)));
+ outgoing_nbytes += CHAR_BYTES (c);
}
}
if (length == 0 || ASCII_BYTE_P (string[length - 1]))
return 0;
i = length - 1;
- while (i > 0 && ! CHAR_HEAD_P (string[i]))
+ while (i >= 0 && ! CHAR_HEAD_P (string[i]))
{
i--;
}
- if (! BASE_LEADING_CODE_P (string[i]))
+ if (i < 0)
+ {
+ /* All characters in `string' are not character head.
+ We must check also preceding bytes at POS.
+ We are sure that the gap is at POS. */
+ string = BEG_ADDR;
+ i = pos_byte - 2;
+ while (i >= 0 && ! CHAR_HEAD_P (string[i]))
+ i--;
+ if (i < 0 || !BASE_LEADING_CODE_P (string[i]))
+ return 0;
+ }
+ else if (!BASE_LEADING_CODE_P (string[i]))
return 0;
if (pos == ZV)
int pos, pos_byte, nbytes;
{
/* Adjust all markers. */
- adjust_markers_for_delete (pos, pos_byte, pos + nbytes, pos_byte);
+ adjust_markers_for_combining (pos, pos_byte, nbytes);
adjust_overlays_for_delete (pos, nbytes);
from_byte + combined_after_bytes);
if (! EQ (current_buffer->undo_list, Qt))
- record_delete (from, deletion);
+ record_delete (from + len, deletion);
}
if (combined_before_bytes)
len, len_byte,
combined_before_bytes, combined_after_bytes);
if (STRINGP (prev_text))
- record_delete (from, prev_text);
+ record_delete (from - !!combined_before_bytes, prev_text);
record_insert (from - !!combined_before_bytes,
len - combined_before_bytes + !!combined_before_bytes);
adjust_overlays_for_delete (from, nchars_del - len);
#ifdef USE_TEXT_PROPERTIES
if (BUF_INTERVALS (current_buffer) != 0)
- offset_intervals (current_buffer, from, len - nchars_del);
+ {
+ offset_intervals (current_buffer, from, len - nchars_del);
+ }
#endif
{
int pos = PT, pos_byte = PT_BYTE;
if (from < PT)
- adjust_point (len - nchars_del + combined_after_bytes,
- len_byte - nbytes_del + combined_after_bytes);
- else if (from == PT && combined_before_bytes)
- adjust_point (0, combined_before_bytes);
+ adjust_point (len - nchars_del, len_byte - nbytes_del);
if (combined_after_bytes)
- combine_bytes (from + len, from_byte + len_byte, combined_after_bytes);
+ {
+ if (combined_before_bytes)
+ combined_before_bytes += combined_after_bytes;
+ else
+ combine_bytes (from + len, from_byte + len_byte,
+ combined_after_bytes);
+ }
if (combined_before_bytes)
combine_bytes (from, from_byte, combined_before_bytes);
/* Note that this does not yet handle markers quite right.
Also it needs to record a single undo-entry that does a replacement
rather than a separate delete and insert.
- That way, undo will also handle markers properly. */
+ That way, undo will also handle markers properly.
+
+ But if MARKERS is 0, don't relocate markers. */
void
-replace_range (from, to, new, prepare, inherit, nomarkers)
+replace_range (from, to, new, prepare, inherit, markers)
Lisp_Object new;
- int from, to, prepare, inherit, nomarkers;
+ int from, to, prepare, inherit, markers;
{
int inschars = XSTRING (new)->size;
int insbytes = STRING_BYTES (XSTRING (new));
int adjusted_inschars;
INTERVAL intervals;
int outgoing_insbytes = insbytes;
+ Lisp_Object deletion;
CHECK_MARKERS ();
if (to < GPT)
gap_left (to, to_byte, 0);
- {
- Lisp_Object deletion;
- deletion = Qnil;
+ deletion = Qnil;
- if (! EQ (current_buffer->undo_list, Qt))
- deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
-
- if (nomarkers)
- /* Relocate all markers pointing into the new, larger gap
- to point at the end of the text before the gap.
- Do this before recording the deletion,
- so that undo handles this after reinserting the text. */
- adjust_markers_for_delete (from, from_byte, to, to_byte);
+ if (! EQ (current_buffer->undo_list, Qt))
+ deletion = make_buffer_string_both (from, from_byte, to, to_byte, 1);
- if (! EQ (current_buffer->undo_list, Qt))
- record_delete (from, deletion);
- }
+ if (markers)
+ /* Relocate all markers pointing into the new, larger gap
+ to point at the end of the text before the gap.
+ Do this before recording the deletion,
+ so that undo handles this after reinserting the text. */
+ adjust_markers_for_delete (from, from_byte, to, to_byte);
GAP_SIZE += nbytes_del;
ZV -= nchars_del;
STRING_MULTIBYTE (new),
! NILP (current_buffer->enable_multibyte_characters));
- /* We have copied text into the gap, but we have not altered
- PT or PT_BYTE yet. So we can pass PT and PT_BYTE
- to these functions and get the same results as we would
- have got earlier on. Meanwhile, GPT_ADDR does point to
+ /* We have copied text into the gap, but we have not marked
+ it as part of the buffer. So we can use the old FROM and FROM_BYTE
+ here, for both the previous text and the following text.
+ Meanwhile, GPT_ADDR does point to
the text that has been stored by copy_text. */
combined_before_bytes
- = count_combining_before (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
+ = count_combining_before (GPT_ADDR, outgoing_insbytes, from, from_byte);
combined_after_bytes
- = count_combining_after (GPT_ADDR, outgoing_insbytes, PT, PT_BYTE);
+ = count_combining_after (GPT_ADDR, outgoing_insbytes, from, from_byte);
/* Record deletion of the surrounding text that combines with
the insertion. This, together with recording the insertion,
deletion = Qnil;
if (! EQ (current_buffer->undo_list, Qt))
- deletion = make_buffer_string_both (PT, PT_BYTE,
- PT + combined_after_bytes,
- PT_BYTE + combined_after_bytes, 1);
+ deletion = make_buffer_string_both (from, from_byte,
+ from + combined_after_bytes,
+ from_byte + combined_after_bytes, 1);
- adjust_markers_for_record_delete (PT, PT_BYTE,
- PT + combined_after_bytes,
- PT_BYTE + combined_after_bytes);
+ adjust_markers_for_record_delete (from, from_byte,
+ from + combined_after_bytes,
+ from_byte + combined_after_bytes);
if (! EQ (current_buffer->undo_list, Qt))
- record_delete (PT, deletion);
+ record_delete (from + inschars, deletion);
}
if (combined_before_bytes)
deletion = Qnil;
if (! EQ (current_buffer->undo_list, Qt))
- deletion = make_buffer_string_both (PT - 1, CHAR_TO_BYTE (PT - 1),
- PT, PT_BYTE, 1);
- adjust_markers_for_record_delete (PT - 1, CHAR_TO_BYTE (PT - 1),
- PT, PT_BYTE);
+ deletion = make_buffer_string_both (from - 1, CHAR_TO_BYTE (from - 1),
+ from, from_byte, 1);
+ adjust_markers_for_record_delete (from - 1, CHAR_TO_BYTE (from - 1),
+ from, from_byte);
if (! EQ (current_buffer->undo_list, Qt))
- record_delete (PT - 1, deletion);
+ record_delete (from - 1, deletion);
}
- record_insert (PT - !!combined_before_bytes,
- inschars - combined_before_bytes + !!combined_before_bytes);
+ if (! EQ (current_buffer->undo_list, Qt))
+ {
+ record_delete (from - !!combined_before_bytes, deletion);
+ record_insert (from - !!combined_before_bytes,
+ (inschars - combined_before_bytes
+ + !!combined_before_bytes));
+ }
GAP_SIZE -= outgoing_insbytes;
GPT += inschars;
adjusting the markers that bound the overlays. */
adjust_overlays_for_delete (from, nchars_del);
adjust_overlays_for_insert (from, inschars);
- if (nomarkers)
+ if (markers)
adjust_markers_for_insert (from, from_byte,
from + inschars, from_byte + outgoing_insbytes,
combined_before_bytes, combined_after_bytes, 0);
#ifdef USE_TEXT_PROPERTIES
- offset_intervals (current_buffer, PT, inschars - nchars_del);
+ offset_intervals (current_buffer, from, inschars - nchars_del);
/* Get the intervals for the part of the string we are inserting--
not including the combined-before bytes. */
/* Relocate point as if it were a marker. */
if (from < PT)
- adjust_point ((from + inschars - (PT < to ? PT : to)
- + combined_after_bytes),
+ adjust_point ((from + inschars - (PT < to ? PT : to)),
(from_byte + outgoing_insbytes
- - (PT_BYTE < to_byte ? PT_BYTE : to_byte)
- + combined_after_bytes));
+ - (PT_BYTE < to_byte ? PT_BYTE : to_byte)));
if (combined_after_bytes)
- combine_bytes (from + inschars, from_byte + outgoing_insbytes,
- combined_after_bytes);
-
+ {
+ if (combined_before_bytes)
+ combined_before_bytes += combined_after_bytes;
+ else
+ combine_bytes (from + inschars, from_byte + outgoing_insbytes,
+ combined_after_bytes);
+ }
if (combined_before_bytes)
combine_bytes (from, from_byte, combined_before_bytes);
MODIFF++;
UNGCPRO;
- signal_after_change (from, nchars_del, PT - from);
+ signal_after_change (from, nchars_del, GPT - from);
}
\f
/* Delete characters in current buffer
Lisp_Object preserve_marker;
struct gcpro gcpro1, gcpro2, gcpro3;
+ if (inhibit_modification_hooks)
+ return;
+
start = make_number (start_int);
end = make_number (end_int);
preserve_marker = Qnil;
signal_after_change (charpos, lendel, lenins)
int charpos, lendel, lenins;
{
+ if (inhibit_modification_hooks)
+ return;
+
/* If we are deferring calls to the after-change functions
and there are no before-change functions,
just record the args that we were going to use. */