summaryrefslogtreecommitdiff
path: root/src/editfns.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c27
1 files changed, 20 insertions, 7 deletions
diff --git a/src/editfns.c b/src/editfns.c
index d15ae59029d..7c58391eb18 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3147,7 +3147,9 @@ SOURCE can be a buffer or a string that names a buffer.
Interactively, prompt for SOURCE.
As far as possible the replacement is non-destructive, i.e. existing
buffer contents, markers, properties, and overlays in the current
-buffer stay intact. */)
+buffer stay intact.
+Warning: this function can be slow if there's a large number of small
+differences between the two buffers. */)
(Lisp_Object source)
{
struct buffer *a = current_buffer;
@@ -3227,11 +3229,16 @@ buffer stay intact. */)
walk backwards, we don’t have to keep the positions in sync. */
while (i >= 0 || j >= 0)
{
+ /* Allow the user to quit if this gets too slow. */
+ maybe_quit ();
+
/* Check whether there is a change (insertion or deletion)
before the current position. */
if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) ||
(j > 0 && bit_is_set (ctx.insertions, j - 1)))
{
+ maybe_quit ();
+
ptrdiff_t end_a = min_a + i;
ptrdiff_t end_b = min_b + j;
/* Find the beginning of the current change run. */
@@ -3305,14 +3312,20 @@ buffer_chars_equal (struct context *ctx,
eassert (pos_b >= BUF_BEGV (ctx->buffer_b));
eassert (pos_b < BUF_ZV (ctx->buffer_b));
+ bool a_unibyte = BUF_ZV (ctx->buffer_a) == BUF_ZV_BYTE (ctx->buffer_a);
+ bool b_unibyte = BUF_ZV (ctx->buffer_b) == BUF_ZV_BYTE (ctx->buffer_b);
+
+ /* Allow the user to escape out of a slow compareseq call. */
+ maybe_quit ();
+
ptrdiff_t bpos_a =
- NILP (BVAR (ctx->buffer_a, enable_multibyte_characters))
- ? pos_a
- : buf_charpos_to_bytepos (ctx->buffer_a, pos_a);
+ a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a);
ptrdiff_t bpos_b =
- NILP (BVAR (ctx->buffer_b, enable_multibyte_characters))
- ? pos_b
- : buf_charpos_to_bytepos (ctx->buffer_b, pos_b);
+ b_unibyte ? pos_b : buf_charpos_to_bytepos (ctx->buffer_b, pos_b);
+
+ if (a_unibyte && b_unibyte)
+ return BUF_FETCH_BYTE (ctx->buffer_a, bpos_a)
+ == BUF_FETCH_BYTE (ctx->buffer_b, bpos_b);
return BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_a, bpos_a)
== BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_b, bpos_b);