summaryrefslogtreecommitdiff
path: root/src/insdel.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1997-06-25 06:50:16 +0000
committerRichard M. Stallman <rms@gnu.org>1997-06-25 06:50:16 +0000
commit4a90066f8aac6989a033065e7d382123db683cbd (patch)
treea8664fa09bb40875bf0635c99c48583fa10c8f66 /src/insdel.c
parent0e623b6de45ed52958d94de4d86c36001f0dbc82 (diff)
downloademacs-4a90066f8aac6989a033065e7d382123db683cbd.tar.gz
(prepare_to_modify_buffer, signal_before_change):
New argument PRESERVE_PTR. (del_range_1): Use PRESERVE_PTR to preserve FROM. Save the length of the range separately. (NULL): Define if not defined.
Diffstat (limited to 'src/insdel.c')
-rw-r--r--src/insdel.c98
1 files changed, 80 insertions, 18 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 12b7eedb58b..098b1670a4f 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -27,6 +27,10 @@ Boston, MA 02111-1307, USA. */
#include "window.h"
#include "blockinput.h"
+#ifndef NULL
+#define NULL 0
+#endif
+
#define min(x, y) ((x) < (y) ? (x) : (y))
static void insert_from_string_1 ();
@@ -441,7 +445,7 @@ insert_1 (string, length, inherit, prepare)
register Lisp_Object temp;
if (prepare)
- prepare_to_modify_buffer (PT, PT);
+ prepare_to_modify_buffer (PT, PT, NULL);
if (PT != GPT)
move_gap (PT);
@@ -512,7 +516,7 @@ insert_from_string_1 (string, pos, length, inherit)
error ("maximum buffer size exceeded");
GCPRO1 (string);
- prepare_to_modify_buffer (PT, PT);
+ prepare_to_modify_buffer (PT, PT, NULL);
if (PT != GPT)
move_gap (PT);
@@ -577,7 +581,7 @@ insert_from_buffer_1 (buf, pos, length, inherit)
if (length + Z != XINT (temp))
error ("maximum buffer size exceeded");
- prepare_to_modify_buffer (PT, PT);
+ prepare_to_modify_buffer (PT, PT, NULL);
if (PT != GPT)
move_gap (PT);
@@ -705,10 +709,17 @@ del_range (from, to)
void
del_range_1 (from, to, prepare)
- register int from, to, prepare;
+ int from, to, prepare;
{
register int numdel;
+ if (prepare)
+ {
+ int range_length = to - from;
+ prepare_to_modify_buffer (from, to, &from);
+ to = from + range_length;
+ }
+
/* Make args be valid */
if (from < BEGV)
from = BEGV;
@@ -724,9 +735,6 @@ del_range_1 (from, to, prepare)
if (to < GPT)
gap_left (to, 0);
- if (prepare)
- prepare_to_modify_buffer (from, to);
-
/* Relocate all markers pointing into the new, larger gap
to point at the end of the text before the gap.
This has to be done before recording the deletion,
@@ -776,7 +784,7 @@ modify_region (buffer, start, end)
if (buffer != old_buffer)
set_buffer_internal (buffer);
- prepare_to_modify_buffer (start, end);
+ prepare_to_modify_buffer (start, end, NULL);
if (start - 1 < beg_unchanged
|| (unchanged_modified == MODIFF
@@ -796,22 +804,40 @@ modify_region (buffer, start, end)
if (buffer != old_buffer)
set_buffer_internal (old_buffer);
}
-
+
/* Check that it is okay to modify the buffer between START and END.
Run the before-change-function, if any. If intervals are in use,
verify that the text to be modified is not read-only, and call
- any modification properties the text may have. */
+ any modification properties the text may have.
+
+ If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
+ by holding its value temporarily in a marker. */
void
-prepare_to_modify_buffer (start, end)
+prepare_to_modify_buffer (start, end, preserve_ptr)
int start, end;
+ int *preserve_ptr;
{
if (!NILP (current_buffer->read_only))
Fbarf_if_buffer_read_only ();
/* Only defined if Emacs is compiled with USE_TEXT_PROPERTIES */
if (BUF_INTERVALS (current_buffer) != 0)
- verify_interval_modification (current_buffer, start, end);
+ {
+ if (preserve_ptr)
+ {
+ Lisp_Object preserve_marker;
+ struct gcpro gcpro1;
+ preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil);
+ GCPRO1 (preserve_marker);
+ verify_interval_modification (current_buffer, start, end);
+ *preserve_ptr = marker_position (preserve_marker);
+ unchain_marker (preserve_marker);
+ UNGCPRO;
+ }
+ else
+ verify_interval_modification (current_buffer, start, end);
+ }
#ifdef CLASH_DETECTION
if (!NILP (current_buffer->file_truename)
@@ -829,7 +855,7 @@ prepare_to_modify_buffer (start, end)
current_buffer->filename);
#endif /* not CLASH_DETECTION */
- signal_before_change (start, end);
+ signal_before_change (start, end, preserve_ptr);
if (current_buffer->newline_cache)
invalidate_region_cache (current_buffer,
@@ -843,29 +869,57 @@ prepare_to_modify_buffer (start, end)
Vdeactivate_mark = Qt;
}
+/* These macros work with an argument named `preserve_ptr'
+ and a local variable named `preserve_marker'. */
+
+#define PRESERVE_VALUE \
+ if (preserve_ptr && NILP (preserve_marker)) \
+ preserve_marker = Fcopy_marker (make_number (*preserve_ptr), Qnil)
+
+#define RESTORE_VALUE \
+ if (! NILP (preserve_marker)) \
+ { \
+ *preserve_ptr = marker_position (preserve_marker); \
+ unchain_marker (preserve_marker); \
+ }
+
/* Signal a change to the buffer immediately before it happens.
- START_INT and END_INT are the bounds of the text to be changed. */
+ START_INT and END_INT are the bounds of the text to be changed.
+
+ If PRESERVE_PTR is nonzero, we relocate *PRESERVE_PTR
+ by holding its value temporarily in a marker. */
void
-signal_before_change (start_int, end_int)
+signal_before_change (start_int, end_int, preserve_ptr)
int start_int, end_int;
+ int *preserve_ptr;
{
Lisp_Object start, end;
+ Lisp_Object preserve_marker;
+ struct gcpro gcpro1;
start = make_number (start_int);
end = make_number (end_int);
+ preserve_marker = Qnil;
+ GCPRO1 (preserve_marker);
/* If buffer is unmodified, run a special hook for that case. */
if (SAVE_MODIFF >= MODIFF
&& !NILP (Vfirst_change_hook)
&& !NILP (Vrun_hooks))
- call1 (Vrun_hooks, Qfirst_change_hook);
+ {
+ PRESERVE_VALUE;
+ 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))
- call2 (Vbefore_change_function, start, end);
+ {
+ PRESERVE_VALUE;
+ call2 (Vbefore_change_function, start, end);
+ }
/* Now run the before-change-functions if any. */
if (!NILP (Vbefore_change_functions))
@@ -875,6 +929,8 @@ signal_before_change (start_int, end_int)
Lisp_Object after_change_functions;
struct gcpro gcpro1, gcpro2;
+ PRESERVE_VALUE;
+
/* "Bind" before-change-functions and after-change-functions
to nil--but in a way that errors don't know about.
That way, if there's an error in them, they will stay nil. */
@@ -898,7 +954,13 @@ signal_before_change (start_int, end_int)
if (!NILP (current_buffer->overlays_before)
|| !NILP (current_buffer->overlays_after))
- report_overlay_modification (start, end, 0, start, end, Qnil);
+ {
+ PRESERVE_VALUE;
+ report_overlay_modification (start, end, 0, start, end, Qnil);
+ }
+
+ RESTORE_VALUE;
+ UNGCPRO;
}
/* Signal a change immediately after it happens.