aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2018-06-23 14:03:10 +0300
committerEli Zaretskii2018-06-23 14:03:10 +0300
commitecc29fbd5a73b55d4624c240b8a2d0a01d699e47 (patch)
tree258ea4edb175fcff9bd9213c85fa34351537b47c
parent8182d648cb18fb048495c761db7c21fbf3c2a624 (diff)
downloademacs-ecc29fbd5a73b55d4624c240b8a2d0a01d699e47.tar.gz
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)
-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.
3147Interactively, prompt for SOURCE. 3147Interactively, prompt for SOURCE.
3148As far as possible the replacement is non-destructive, i.e. existing 3148As far as possible the replacement is non-destructive, i.e. existing
3149buffer contents, markers, properties, and overlays in the current 3149buffer contents, markers, properties, and overlays in the current
3150buffer stay intact. */) 3150buffer stay intact.
3151Warning: this function can be slow if there's a large number of small
3152differences between the two buffers. */)
3151 (Lisp_Object source) 3153 (Lisp_Object source)
3152{ 3154{
3153 struct buffer *a = current_buffer; 3155 struct buffer *a = current_buffer;
@@ -3227,11 +3229,16 @@ buffer stay intact. */)
3227 walk backwards, we don’t have to keep the positions in sync. */ 3229 walk backwards, we don’t have to keep the positions in sync. */
3228 while (i >= 0 || j >= 0) 3230 while (i >= 0 || j >= 0)
3229 { 3231 {
3232 /* Allow the user to quit if this gets too slow. */
3233 maybe_quit ();
3234
3230 /* Check whether there is a change (insertion or deletion) 3235 /* Check whether there is a change (insertion or deletion)
3231 before the current position. */ 3236 before the current position. */
3232 if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) || 3237 if ((i > 0 && bit_is_set (ctx.deletions, i - 1)) ||
3233 (j > 0 && bit_is_set (ctx.insertions, j - 1))) 3238 (j > 0 && bit_is_set (ctx.insertions, j - 1)))
3234 { 3239 {
3240 maybe_quit ();
3241
3235 ptrdiff_t end_a = min_a + i; 3242 ptrdiff_t end_a = min_a + i;
3236 ptrdiff_t end_b = min_b + j; 3243 ptrdiff_t end_b = min_b + j;
3237 /* Find the beginning of the current change run. */ 3244 /* Find the beginning of the current change run. */
@@ -3305,14 +3312,20 @@ buffer_chars_equal (struct context *ctx,
3305 eassert (pos_b >= BUF_BEGV (ctx->buffer_b)); 3312 eassert (pos_b >= BUF_BEGV (ctx->buffer_b));
3306 eassert (pos_b < BUF_ZV (ctx->buffer_b)); 3313 eassert (pos_b < BUF_ZV (ctx->buffer_b));
3307 3314
3315 bool a_unibyte = BUF_ZV (ctx->buffer_a) == BUF_ZV_BYTE (ctx->buffer_a);
3316 bool b_unibyte = BUF_ZV (ctx->buffer_b) == BUF_ZV_BYTE (ctx->buffer_b);
3317
3318 /* Allow the user to escape out of a slow compareseq call. */
3319 maybe_quit ();
3320
3308 ptrdiff_t bpos_a = 3321 ptrdiff_t bpos_a =
3309 NILP (BVAR (ctx->buffer_a, enable_multibyte_characters)) 3322 a_unibyte ? pos_a : buf_charpos_to_bytepos (ctx->buffer_a, pos_a);
3310 ? pos_a
3311 : buf_charpos_to_bytepos (ctx->buffer_a, pos_a);
3312 ptrdiff_t bpos_b = 3323 ptrdiff_t bpos_b =
3313 NILP (BVAR (ctx->buffer_b, enable_multibyte_characters)) 3324 b_unibyte ? pos_b : buf_charpos_to_bytepos (ctx->buffer_b, pos_b);
3314 ? pos_b 3325
3315 : buf_charpos_to_bytepos (ctx->buffer_b, pos_b); 3326 if (a_unibyte && b_unibyte)
3327 return BUF_FETCH_BYTE (ctx->buffer_a, bpos_a)
3328 == BUF_FETCH_BYTE (ctx->buffer_b, bpos_b);
3316 3329
3317 return BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_a, bpos_a) 3330 return BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_a, bpos_a)
3318 == BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_b, bpos_b); 3331 == BUF_FETCH_CHAR_AS_MULTIBYTE (ctx->buffer_b, bpos_b);