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;
void
insert_from_gap (ptrdiff_t nchars, ptrdiff_t nbytes, bool text_at_gap_tail)
{
- int ins_charpos = GPT;
- int ins_bytepos = GPT_BYTE;
+ ptrdiff_t ins_charpos = GPT, ins_bytepos = GPT_BYTE;
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++;
ptrdiff_t outgoing_nbytes = incoming_nbytes;
INTERVAL intervals;
+ if (nchars == 0)
+ return;
+
/* Make OUTGOING_NBYTES describe the text
as it will be inserted in this buffer. */
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;
adjust_markers_for_insert (from, from_byte,
from + len, from_byte + len_byte, 0);
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
- {
- if (nchars_del > 0)
- record_delete (from, prev_text);
- record_insert (from, len);
- }
+ if (nchars_del > 0)
+ record_delete (from, prev_text);
+ record_insert (from, len);
if (len > nchars_del)
adjust_overlays_for_insert (from, len - nchars_del);
emacs_abort ();
#endif
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
+ /* Record the insertion first, so that when we undo,
+ the deletion will be undone first. Thus, undo
+ will insert before deleting, and thus will keep
+ the markers before and after this text separate. */
+ if (!NILP (deletion))
{
- /* Record the insertion first, so that when we undo,
- the deletion will be undone first. Thus, undo
- will insert before deleting, and thus will keep
- the markers before and after this text separate. */
record_insert (from + SCHARS (deletion), inschars);
record_delete (from, deletion);
}
so that undo handles this after reinserting the text. */
adjust_markers_for_delete (from, from_byte, to, to_byte);
- if (! EQ (BVAR (current_buffer, undo_list), Qt))
- record_delete (from, deletion);
+ record_delete (from, deletion);
MODIFF++;
CHARS_MODIFF = MODIFF;
return deletion;
}
-/* Call this if you're about to change the region of current buffer
+/* Call this if you're about to change the text of current buffer
from character positions START to END. This checks the read-only
properties of the region, calls the necessary modification hooks,
and warns the next redisplay that it should pay attention to that
- area.
-
- If PRESERVE_CHARS_MODIFF, do not update CHARS_MODIFF.
- Otherwise set CHARS_MODIFF to the new value of MODIFF. */
+ area. */
void
-modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
+modify_text (ptrdiff_t start, ptrdiff_t end)
{
prepare_to_modify_buffer (start, end, NULL);
BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
-
if (MODIFF <= SAVE_MODIFF)
record_first_change ();
MODIFF++;
- if (! preserve_chars_modiff)
- CHARS_MODIFF = MODIFF;
+ CHARS_MODIFF = MODIFF;
bset_point_before_scroll (current_buffer, Qnil);
}
+Lisp_Object Qregion_extract_function;
+
/* Check that it is okay to modify the buffer between START and END,
which are char positions.
by holding its value temporarily in a marker. */
void
-prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
- ptrdiff_t *preserve_ptr)
+prepare_to_modify_buffer_1 (ptrdiff_t start, ptrdiff_t end,
+ ptrdiff_t *preserve_ptr)
{
struct buffer *base_buffer;
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))
{
#endif /* not CLASH_DETECTION */
/* If `select-active-regions' is non-nil, save the region text. */
+ /* FIXME: Move this to Elisp (via before-change-functions). */
if (!NILP (BVAR (current_buffer, mark_active))
&& !inhibit_modification_hooks
&& XMARKER (BVAR (current_buffer, mark))->buffer
? EQ (CAR_SAFE (Vtransient_mark_mode), Qonly)
: (!NILP (Vselect_active_regions)
&& !NILP (Vtransient_mark_mode))))
- {
- ptrdiff_t b = marker_position (BVAR (current_buffer, mark));
- ptrdiff_t e = PT;
- if (b < e)
- Vsaved_region_selection = make_buffer_string (b, e, 0);
- else if (b > e)
- Vsaved_region_selection = make_buffer_string (e, b, 0);
- }
+ Vsaved_region_selection
+ = call1 (Fsymbol_value (Qregion_extract_function), Qnil);
signal_before_change (start, end, preserve_ptr);
+ Vdeactivate_mark = Qt;
+}
- 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);
+/* Like above, but called when we know that the buffer text
+ will be modified and region caches should be invalidated. */
- Vdeactivate_mark = Qt;
+void
+prepare_to_modify_buffer (ptrdiff_t start, ptrdiff_t end,
+ ptrdiff_t *preserve_ptr)
+{
+ prepare_to_modify_buffer_1 (start, end, preserve_ptr);
+ invalidate_buffer_caches (current_buffer, start, end);
}
-\f
+
+/* 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)
+{
+ 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'
and a local variable named `preserve_marker'. */
inhibit_modification_hooks = 0;
DEFSYM (Qinhibit_modification_hooks, "inhibit-modification-hooks");
+ DEFSYM (Qregion_extract_function, "region-extract-function");
+
defsubr (&Scombine_after_change_execute);
}