/* Buffer insertion/deletion and gap motion for GNU Emacs.
- Copyright (C) 1985-1986, 1993-1995, 1997-2015 Free Software
+ Copyright (C) 1985-1986, 1993-1995, 1997-2016 Free Software
Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
if (i == 0)
break;
/* If a quit is requested, stop copying now.
- Change BYTEPOS to be where we have actually moved the gap to. */
+ Change BYTEPOS to be where we have actually moved the gap to.
+ Note that this cannot happen when we are called to make the
+ gap larger or smaller, since make_gap_larger and
+ make_gap_smaller prevent QUIT by setting inhibit-quit. */
if (QUITP)
{
bytepos = new_s1;
if (i == 0)
break;
/* If a quit is requested, stop copying now.
- Change BYTEPOS to be where we have actually moved the gap to. */
+ Change BYTEPOS to be where we have actually moved the gap to.
+ Note that this cannot happen when we are called to make the
+ gap larger or smaller, since make_gap_larger and
+ make_gap_smaller prevent QUIT by setting inhibit-quit. */
if (QUITP)
{
bytepos = new_s1;
enlarge_buffer_text (current_buffer, nbytes_added);
- /* Prevent quitting in move_gap. */
+ /* Prevent quitting in gap_left. We cannot allow a QUIT there,
+ because that would leave the buffer text in an inconsistent
+ state, with 2 gap holes instead of just one. */
tem = Vinhibit_quit;
Vinhibit_quit = Qt;
if (GAP_SIZE - nbytes_removed < GAP_BYTES_MIN)
nbytes_removed = GAP_SIZE - GAP_BYTES_MIN;
- /* Prevent quitting in move_gap. */
+ /* Prevent quitting in gap_right. We cannot allow a QUIT there,
+ because that would leave the buffer text in an inconsistent
+ state, with 2 gap holes instead of just one. */
tem = Vinhibit_quit;
Vinhibit_quit = Qt;
bset_point_before_scroll (current_buffer, Qnil);
}
+/* Signal that we are about to make a change that may result in new
+ undo information.
+ */
+static void
+run_undoable_change (void)
+{
+ if (EQ (BVAR (current_buffer, undo_list), Qt))
+ return;
+
+ call0 (Qundo_auto__undoable_change);
+}
+
/* Check that it is okay to modify the buffer between START and END,
which are char positions.
any modification properties the text may have.
If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
- by holding its value temporarily in a marker. */
+ by holding its value temporarily in a marker.
+
+ This function runs Lisp, which means it can GC, which means it can
+ compact buffers, including the current buffer being worked on here.
+ So don't you dare calling this function while manipulating the gap,
+ or during some other similar "critical section". */
void
prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
if (!NILP (BVAR (current_buffer, read_only)))
Fbarf_if_buffer_read_only (temp);
+ run_undoable_change();
+
bset_redisplay (current_buffer);
if (buffer_intervals (current_buffer))
combine_after_change_list = Qnil;
combine_after_change_buffer = Qnil;
+ DEFSYM (Qundo_auto__undoable_change, "undo-auto--undoable-change");
+
DEFVAR_LISP ("combine-after-change-calls", Vcombine_after_change_calls,
doc: /* Used internally by the function `combine-after-change-calls' macro. */);
Vcombine_after_change_calls = Qnil;