/* Buffer insertion/deletion and gap motion for GNU Emacs.
- Copyright (C) 1985-1986, 1993-1995, 1997-2013 Free Software
- Foundation, Inc.
+
+Copyright (C) 1985-1986, 1993-1995, 1997-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
adjust_markers_for_delete (ptrdiff_t from, ptrdiff_t from_byte,
ptrdiff_t to, ptrdiff_t to_byte)
{
- Lisp_Object marker;
- register struct Lisp_Marker *m;
- register ptrdiff_t charpos;
+ struct Lisp_Marker *m;
+ ptrdiff_t charpos;
for (m = BUF_MARKERS (current_buffer); m; m = m->next)
{
/* Here's the case where a marker is inside text being deleted. */
else if (charpos > from)
{
- 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. */
- XSETMISC (marker, m);
- 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. */
- XSETMISC (marker, m);
- record_marker_adjustment (marker, to - charpos);
- }
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. */
- XSETMISC (marker, m);
- record_marker_adjustment (marker, to - from);
- }
}
}
eassert (GPT <= GPT_BYTE);
- /* The insert may have been in the unchanged region, so check again. */
+ /* The insert may have been in the unchanged region, so check again. */
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
eassert (GPT <= GPT_BYTE);
- /* The insert may have been in the unchanged region, so check again. */
+ /* The insert may have been in the unchanged region, so check again. */
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
nchars = nbytes;
+ /* No need to call prepare_to_modify_buffer, since this is called
+ from places that replace some region with a different text, so
+ prepare_to_modify_buffer was already called by the deletion part
+ of this dance. */
+ invalidate_buffer_caches (current_buffer, GPT, GPT);
record_insert (GPT, nchars);
MODIFF++;
eassert (GPT <= GPT_BYTE);
- /* The insert may have been in the unchanged region, so check again. */
+ /* The insert may have been in the unchanged region, so check again. */
if (Z - GPT < END_UNCHANGED)
END_UNCHANGED = Z - GPT;
from + len, from_byte + len_byte, 0);
if (nchars_del > 0)
- record_delete (from, prev_text);
+ record_delete (from, prev_text, false);
record_insert (from, len);
if (len > nchars_del)
if (!NILP (deletion))
{
record_insert (from + SCHARS (deletion), inschars);
- record_delete (from, deletion);
+ record_delete (from, deletion, false);
}
GAP_SIZE -= outgoing_insbytes;
else
deletion = Qnil;
- /* 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. */
+ /* Record marker adjustments, and text deletion into undo
+ history. */
+ record_delete (from, deletion, true);
+
+ /* Relocate all markers pointing into the new, larger gap to point
+ at the end of the text before the gap. */
adjust_markers_for_delete (from, from_byte, to, to_byte);
- record_delete (from, deletion);
MODIFF++;
CHARS_MODIFF = MODIFF;
bset_point_before_scroll (current_buffer, Qnil);
}
-static Lisp_Object Qregion_extract_function;
+Lisp_Object Qregion_extract_function;
/* Check that it is okay to modify the buffer between START and END,
which are char positions.
if (!NILP (BVAR (current_buffer, read_only)))
Fbarf_if_buffer_read_only ();
- /* If we're modifying the buffer other than shown in a selected window,
- let redisplay consider other windows if this buffer is visible. */
- if (XBUFFER (XWINDOW (selected_window)->contents) != current_buffer
- && buffer_window_count (current_buffer))
- ++windows_or_buffers_changed;
+ bset_redisplay (current_buffer);
if (buffer_intervals (current_buffer))
{
else
base_buffer = current_buffer;
-#ifdef CLASH_DETECTION
if (!NILP (BVAR (base_buffer, file_truename))
/* Make binding buffer-file-name to nil effective. */
&& !NILP (BVAR (base_buffer, filename))
&& SAVE_MODIFF >= MODIFF)
lock_file (BVAR (base_buffer, file_truename));
-#else
- /* At least warn if this file has changed on disk since it was visited. */
- if (!NILP (BVAR (base_buffer, filename))
- && SAVE_MODIFF >= MODIFF
- && NILP (Fverify_visited_file_modtime (Fcurrent_buffer ()))
- && !NILP (Ffile_exists_p (BVAR (base_buffer, filename))))
- call1 (intern ("ask-user-about-supersession-threat"),
- BVAR (base_buffer,filename));
-#endif /* not CLASH_DETECTION */
/* If `select-active-regions' is non-nil, save the region text. */
/* FIXME: Move this to Elisp (via before-change-functions). */
ptrdiff_t *preserve_ptr)
{
prepare_to_modify_buffer_1 (start, end, preserve_ptr);
+ invalidate_buffer_caches (current_buffer, start, end);
+}
- if (current_buffer->newline_cache)
- invalidate_region_cache (current_buffer,
- current_buffer->newline_cache,
- start - BEG, Z - end);
- if (current_buffer->width_run_cache)
- invalidate_region_cache (current_buffer,
- current_buffer->width_run_cache,
- start - BEG, Z - end);
- if (current_buffer->bidi_paragraph_cache)
- invalidate_region_cache (current_buffer,
- current_buffer->bidi_paragraph_cache,
- start - BEG, Z - end);
+/* Invalidate the caches maintained by the buffer BUF, if any, for the
+ region between buffer positions START and END. */
+void
+invalidate_buffer_caches (struct buffer *buf, ptrdiff_t start, ptrdiff_t end)
+{
+ /* Indirect buffers usually have their caches set to NULL, but we
+ need to consider the caches of their base buffer. */
+ if (buf->base_buffer)
+ buf = buf->base_buffer;
+ if (buf->newline_cache)
+ invalidate_region_cache (buf,
+ buf->newline_cache,
+ start - BUF_BEG (buf), BUF_Z (buf) - end);
+ if (buf->width_run_cache)
+ invalidate_region_cache (buf,
+ buf->width_run_cache,
+ start - BUF_BEG (buf), BUF_Z (buf) - end);
+ if (buf->bidi_paragraph_cache)
+ invalidate_region_cache (buf,
+ buf->bidi_paragraph_cache,
+ start - BUF_BEG (buf), BUF_Z (buf) - end);
}
/* These macros work with an argument named `preserve_ptr'