diff options
author | Eli Zaretskii <eliz@gnu.org> | 2018-06-23 14:03:10 +0300 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2018-06-23 14:03:10 +0300 |
commit | ecc29fbd5a73b55d4624c240b8a2d0a01d699e47 (patch) | |
tree | 258ea4edb175fcff9bd9213c85fa34351537b47c /src/editfns.c | |
parent | 8182d648cb18fb048495c761db7c21fbf3c2a624 (diff) | |
download | emacs-ecc29fbd5a73b55d4624c240b8a2d0a01d699e47.tar.gz emacs-ecc29fbd5a73b55d4624c240b8a2d0a01d699e47.tar.bz2 emacs-ecc29fbd5a73b55d4624c240b8a2d0a01d699e47.zip |
Improve responsiveness while in 'replace-buffer-contents'
* src/editfns.c (buffer_chars_equal): Avoid calling
buf_charpos_to_bytepos when the buffer is plain-ASCII.
Suggested by Milan Stanojević <mstanojevic@janestreet.com>.
Call maybe_quit to improve responsiveness.
(Freplace_buffer_contents): Call maybe_quit. Warn in the doc
string that the function could be slow. (Bug#31888)
Diffstat (limited to 'src/editfns.c')
-rw-r--r-- | src/editfns.c | 27 |
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); |