diff options
| author | Eli Zaretskii | 2018-06-23 14:03:10 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2018-06-23 14:03:10 +0300 |
| commit | ecc29fbd5a73b55d4624c240b8a2d0a01d699e47 (patch) | |
| tree | 258ea4edb175fcff9bd9213c85fa34351537b47c | |
| parent | 8182d648cb18fb048495c761db7c21fbf3c2a624 (diff) | |
| download | emacs-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.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. | |||
| 3147 | Interactively, prompt for SOURCE. | 3147 | Interactively, prompt for SOURCE. |
| 3148 | As far as possible the replacement is non-destructive, i.e. existing | 3148 | As far as possible the replacement is non-destructive, i.e. existing |
| 3149 | buffer contents, markers, properties, and overlays in the current | 3149 | buffer contents, markers, properties, and overlays in the current |
| 3150 | buffer stay intact. */) | 3150 | buffer stay intact. |
| 3151 | Warning: this function can be slow if there's a large number of small | ||
| 3152 | differences 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); |