/* Buffer insertion/deletion and gap motion for GNU Emacs.
- Copyright (C) 1985, 86,93,94,95,97,98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86,93,94,95,97,98, 1999, 2000 Free Software Foundation, Inc.
This file is part of GNU Emacs.
m->charpos -= to - from;
m->bytepos -= to_byte - from_byte;
}
-
/* Here's the case where a marker is inside text being deleted. */
else if (charpos > from)
{
- record_marker_adjustment (marker, from - charpos);
+ if (! m->insertion_type)
+ /* Normal markers will end up at the beginning of the
+ re-inserted text after undoing a deletion, and must be
+ adjusted to move them to the correct place. */
+ record_marker_adjustment (marker, from - charpos);
+ else if (charpos < to)
+ /* Before-insertion markers will automatically move forward
+ upon re-inserting the deleted text, so we have to arrange
+ for them to move backward to the correct position. */
+ record_marker_adjustment (marker, charpos - to);
+
m->charpos = from;
m->bytepos = from_byte;
}
+ /* Here's the case where a before-insertion marker is immediately
+ before the deleted region. */
+ else if (charpos == from && m->insertion_type)
+ {
+ /* Undoing the change uses normal insertion, which will
+ incorrectly make MARKER move forward, so we arrange for it
+ to then move backward to the correct place at the beginning
+ of the deleted region. */
+ record_marker_adjustment (marker, to - from);
+ }
marker = m->chain;
}
\f
/* Adjust markers for a replacement of a text at FROM (FROM_BYTE) of
length OLD_CHARS (OLD_BYTES) to a new text of length NEW_CHARS
- (NEW_BYTES). */
+ (NEW_BYTES). It is assumed that OLD_CHARS > 0, i.e., this is not
+ an insertion. */
static void
adjust_markers_for_replace (from, from_byte, old_chars, old_bytes,
{
register struct Lisp_Marker *m = XMARKER (marker);
- if (m->bytepos >= prev_to_byte
- && (old_bytes != 0
- /* If this is an insertion (replacing 0 chars),
- reject the case of a marker that is at the
- insertion point and should stay before the insertion. */
- || m->bytepos > from_byte || m->insertion_type))
+ if (m->bytepos >= prev_to_byte)
{
- m->charpos = min (from + new_chars, m->charpos + diff_chars);
- m->bytepos = min (from_byte + new_bytes, m->bytepos + diff_bytes);
+ m->charpos += diff_chars;
+ m->bytepos += diff_bytes;
}
- else if (m->bytepos >= from_byte)
+ else if (m->bytepos > from_byte)
{
m->charpos = from;
m->bytepos = from_byte;
>= ((unsigned) 1 << (min (BITS_PER_INT, VALBITS) - 1)))
error ("Buffer exceeds maximum size");
- BLOCK_INPUT;
- /* We allocate extra 1-byte `\0' at the tail for anchoring a search. */
- result = BUFFER_REALLOC (BEG_ADDR, (Z_BYTE - BEG_BYTE
- + GAP_SIZE + nbytes_added + 1));
-
- if (result == 0)
- {
- UNBLOCK_INPUT;
- memory_full ();
- }
-
- /* We can't unblock until the new address is properly stored. */
- BEG_ADDR = result;
- UNBLOCK_INPUT;
+ enlarge_buffer_text (current_buffer, nbytes_added);
/* Prevent quitting in move_gap. */
tem = Vinhibit_quit;
GPT += len; GPT_BYTE += len_byte;
if (GAP_SIZE > 0) *(GPT_ADDR) = 0; /* Put an anchor. */
- adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
- len, len_byte);
+ if (nchars_del > 0)
+ adjust_markers_for_replace (from, from_byte, nchars_del, nbytes_del,
+ len, len_byte);
+ else
+ adjust_markers_for_insert (from, from_byte,
+ from + len, from_byte + len_byte, 0);
if (! EQ (current_buffer->undo_list, Qt))
{
CHECK_MARKERS ();
GCPRO1 (new);
+ deletion = Qnil;
if (prepare)
{
call1 (Vrun_hooks, Qfirst_change_hook);
}
- /* Run the before-change-function if any.
- We don't bother "binding" this variable to nil
- because it is obsolete anyway and new code should not use it. */
- if (!NILP (Vbefore_change_function))
- {
- PRESERVE_VALUE;
- PRESERVE_START_END;
- call2 (Vbefore_change_function, FETCH_START, FETCH_END);
- }
-
/* Now run the before-change-functions if any. */
if (!NILP (Vbefore_change_functions))
{
and there are no before-change functions,
just record the args that we were going to use. */
if (! NILP (Vcombine_after_change_calls)
- && NILP (Vbefore_change_function) && NILP (Vbefore_change_functions)
+ && NILP (Vbefore_change_functions)
&& NILP (current_buffer->overlays_before)
&& NILP (current_buffer->overlays_after))
{
if (!NILP (combine_after_change_list))
Fcombine_after_change_execute ();
- /* Run the after-change-function if any.
- We don't bother "binding" this variable to nil
- because it is obsolete anyway and new code should not use it. */
- if (!NILP (Vafter_change_function))
- call3 (Vafter_change_function,
- make_number (charpos), make_number (charpos + lenins),
- make_number (lendel));
-
if (!NILP (Vafter_change_functions))
{
Lisp_Object args[4];