diff options
| author | Gregory Heytings | 2022-07-22 10:03:13 +0000 |
|---|---|---|
| committer | Gregory Heytings | 2022-07-22 12:06:31 +0200 |
| commit | 874e2525035d45efa6fa374a2ebec3740ecc1457 (patch) | |
| tree | 059221aee889a88f558802014c5680017eaec1d0 /src | |
| parent | 616da8fa8efa9023f56fa731072d877e2150afbc (diff) | |
| download | emacs-874e2525035d45efa6fa374a2ebec3740ecc1457.tar.gz emacs-874e2525035d45efa6fa374a2ebec3740ecc1457.zip | |
Improve font locking in buffers with long lines (bug#56682).
* src/dispextern.h (struct it): New 'narrowed_zv' field.
* src/xdisp.c (init_iterator): Set the field.
(get_narrowed_zv): New function to set the field.
(handle_fontified_prop): Use the field, together with 'narrowed_begv',
to narrow the portion of the buffer that 'Vfontification_functions'
will see. Also bind 'inhibit-widen'.
(get_narrowed_len): New function, factored out of 'get_narrowed_begv'.
(unwind_narrowed_zv): New function.
* src/editfns.c (syms_of_editfns): New variable and symbol 'inhibit-widen'.
(Fwiden): Do nothing when 'inhibit-widen' is non-nil.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dispextern.h | 5 | ||||
| -rw-r--r-- | src/editfns.c | 12 | ||||
| -rw-r--r-- | src/xdisp.c | 46 |
3 files changed, 56 insertions, 7 deletions
diff --git a/src/dispextern.h b/src/dispextern.h index 1cdfdca74c0..bafa98161d0 100644 --- a/src/dispextern.h +++ b/src/dispextern.h | |||
| @@ -2336,6 +2336,10 @@ struct it | |||
| 2336 | optimize display (see the SET_WITH_NARROWED_BEGV macro). */ | 2336 | optimize display (see the SET_WITH_NARROWED_BEGV macro). */ |
| 2337 | ptrdiff_t narrowed_begv; | 2337 | ptrdiff_t narrowed_begv; |
| 2338 | 2338 | ||
| 2339 | /* Alternate end position of the buffer that may be used to | ||
| 2340 | optimize display. */ | ||
| 2341 | ptrdiff_t narrowed_zv; | ||
| 2342 | |||
| 2339 | /* C string to iterate over. Non-null means get characters from | 2343 | /* C string to iterate over. Non-null means get characters from |
| 2340 | this string, otherwise characters are read from current_buffer | 2344 | this string, otherwise characters are read from current_buffer |
| 2341 | or it->string. */ | 2345 | or it->string. */ |
| @@ -3401,6 +3405,7 @@ void redisplay_preserve_echo_area (int); | |||
| 3401 | void init_iterator (struct it *, struct window *, ptrdiff_t, | 3405 | void init_iterator (struct it *, struct window *, ptrdiff_t, |
| 3402 | ptrdiff_t, struct glyph_row *, enum face_id); | 3406 | ptrdiff_t, struct glyph_row *, enum face_id); |
| 3403 | ptrdiff_t get_narrowed_begv (struct window *w); | 3407 | ptrdiff_t get_narrowed_begv (struct window *w); |
| 3408 | ptrdiff_t get_narrowed_zv (struct window *w); | ||
| 3404 | void init_iterator_to_row_start (struct it *, struct window *, | 3409 | void init_iterator_to_row_start (struct it *, struct window *, |
| 3405 | struct glyph_row *); | 3410 | struct glyph_row *); |
| 3406 | void start_display (struct it *, struct window *, struct text_pos); | 3411 | void start_display (struct it *, struct window *, struct text_pos); |
diff --git a/src/editfns.c b/src/editfns.c index 4587b1132b1..6dec2d468c0 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -2661,6 +2661,8 @@ DEFUN ("widen", Fwiden, Swiden, 0, 0, "", | |||
| 2661 | This allows the buffer's full text to be seen and edited. */) | 2661 | This allows the buffer's full text to be seen and edited. */) |
| 2662 | (void) | 2662 | (void) |
| 2663 | { | 2663 | { |
| 2664 | if (!NILP (Vinhibit_widen)) | ||
| 2665 | return Qnil; | ||
| 2664 | if (BEG != BEGV || Z != ZV) | 2666 | if (BEG != BEGV || Z != ZV) |
| 2665 | current_buffer->clip_changed = 1; | 2667 | current_buffer->clip_changed = 1; |
| 2666 | BEGV = BEG; | 2668 | BEGV = BEG; |
| @@ -4457,6 +4459,7 @@ syms_of_editfns (void) | |||
| 4457 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); | 4459 | DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); |
| 4458 | DEFSYM (Qwall, "wall"); | 4460 | DEFSYM (Qwall, "wall"); |
| 4459 | DEFSYM (Qpropertize, "propertize"); | 4461 | DEFSYM (Qpropertize, "propertize"); |
| 4462 | DEFSYM (Qinhibit_widen, "inhibit-widen"); | ||
| 4460 | 4463 | ||
| 4461 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, | 4464 | DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, |
| 4462 | doc: /* Non-nil means text motion commands don't notice fields. */); | 4465 | doc: /* Non-nil means text motion commands don't notice fields. */); |
| @@ -4517,6 +4520,15 @@ This variable is experimental; email 32252@debbugs.gnu.org if you need | |||
| 4517 | it to be non-nil. */); | 4520 | it to be non-nil. */); |
| 4518 | binary_as_unsigned = false; | 4521 | binary_as_unsigned = false; |
| 4519 | 4522 | ||
| 4523 | DEFVAR_LISP ("inhibit-widen", Vinhibit_widen, | ||
| 4524 | doc: /* Non-nil inhibits the `widen' function. | ||
| 4525 | |||
| 4526 | Do NOT set this globally to a non-nil value, as doing that will | ||
| 4527 | disable the `widen' function everywhere, including the \\[widen\] | ||
| 4528 | command. This variable is intended to be let-bound around code | ||
| 4529 | that needs to disable `widen' temporarily. */); | ||
| 4530 | Vinhibit_widen = Qnil; | ||
| 4531 | |||
| 4520 | defsubr (&Spropertize); | 4532 | defsubr (&Spropertize); |
| 4521 | defsubr (&Schar_equal); | 4533 | defsubr (&Schar_equal); |
| 4522 | defsubr (&Sgoto_char); | 4534 | defsubr (&Sgoto_char); |
diff --git a/src/xdisp.c b/src/xdisp.c index ebeaf2a3dab..caa421c2818 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -3426,7 +3426,10 @@ init_iterator (struct it *it, struct window *w, | |||
| 3426 | } | 3426 | } |
| 3427 | 3427 | ||
| 3428 | if (current_buffer->long_line_optimizations_p) | 3428 | if (current_buffer->long_line_optimizations_p) |
| 3429 | it->narrowed_begv = get_narrowed_begv (w); | 3429 | { |
| 3430 | it->narrowed_begv = get_narrowed_begv (w); | ||
| 3431 | it->narrowed_zv = get_narrowed_zv (w); | ||
| 3432 | } | ||
| 3430 | 3433 | ||
| 3431 | /* If a buffer position was specified, set the iterator there, | 3434 | /* If a buffer position was specified, set the iterator there, |
| 3432 | getting overlays and face properties from that position. */ | 3435 | getting overlays and face properties from that position. */ |
| @@ -3494,29 +3497,49 @@ init_iterator (struct it *it, struct window *w, | |||
| 3494 | CHECK_IT (it); | 3497 | CHECK_IT (it); |
| 3495 | } | 3498 | } |
| 3496 | 3499 | ||
| 3497 | /* Compute a suitable alternate value for BEGV that may be used | 3500 | /* Compute a suitable alternate value for BEGV and ZV that may be used |
| 3498 | temporarily to optimize display if the buffer in window W contains | 3501 | temporarily to optimize display if the buffer in window W contains |
| 3499 | long lines. */ | 3502 | long lines. */ |
| 3500 | 3503 | ||
| 3501 | ptrdiff_t | 3504 | static int |
| 3502 | get_narrowed_begv (struct window *w) | 3505 | get_narrowed_len (struct window *w) |
| 3503 | { | 3506 | { |
| 3504 | int len, fact; ptrdiff_t begv; | 3507 | int fact; |
| 3505 | /* In a character-only terminal, only one font size is used, so we | 3508 | /* In a character-only terminal, only one font size is used, so we |
| 3506 | can use a smaller factor. */ | 3509 | can use a smaller factor. */ |
| 3507 | fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3; | 3510 | fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3; |
| 3508 | len = fact * (window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) * | 3511 | return fact * (window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) * |
| 3509 | window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)); | 3512 | window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)); |
| 3513 | } | ||
| 3514 | |||
| 3515 | ptrdiff_t | ||
| 3516 | get_narrowed_begv (struct window *w) | ||
| 3517 | { | ||
| 3518 | int len = get_narrowed_len (w); | ||
| 3519 | ptrdiff_t begv; | ||
| 3510 | begv = max ((window_point (w) / len - 1) * len, BEGV); | 3520 | begv = max ((window_point (w) / len - 1) * len, BEGV); |
| 3511 | return begv == BEGV ? 0 : begv; | 3521 | return begv == BEGV ? 0 : begv; |
| 3512 | } | 3522 | } |
| 3513 | 3523 | ||
| 3524 | ptrdiff_t | ||
| 3525 | get_narrowed_zv (struct window *w) | ||
| 3526 | { | ||
| 3527 | int len = get_narrowed_len (w); | ||
| 3528 | return min ((window_point (w) / len + 1) * len, ZV); | ||
| 3529 | } | ||
| 3530 | |||
| 3514 | static void | 3531 | static void |
| 3515 | unwind_narrowed_begv (Lisp_Object point_min) | 3532 | unwind_narrowed_begv (Lisp_Object point_min) |
| 3516 | { | 3533 | { |
| 3517 | SET_BUF_BEGV (current_buffer, XFIXNUM (point_min)); | 3534 | SET_BUF_BEGV (current_buffer, XFIXNUM (point_min)); |
| 3518 | } | 3535 | } |
| 3519 | 3536 | ||
| 3537 | static void | ||
| 3538 | unwind_narrowed_zv (Lisp_Object point_max) | ||
| 3539 | { | ||
| 3540 | SET_BUF_ZV (current_buffer, XFIXNUM (point_max)); | ||
| 3541 | } | ||
| 3542 | |||
| 3520 | /* Set DST to EXPR. When IT indicates that BEGV should temporarily be | 3543 | /* Set DST to EXPR. When IT indicates that BEGV should temporarily be |
| 3521 | updated to optimize display, evaluate EXPR with an updated BEGV. */ | 3544 | updated to optimize display, evaluate EXPR with an updated BEGV. */ |
| 3522 | 3545 | ||
| @@ -4372,6 +4395,15 @@ handle_fontified_prop (struct it *it) | |||
| 4372 | bool old_clip_changed = current_buffer->clip_changed; | 4395 | bool old_clip_changed = current_buffer->clip_changed; |
| 4373 | bool saved_inhibit_flag = it->f->inhibit_clear_image_cache; | 4396 | bool saved_inhibit_flag = it->f->inhibit_clear_image_cache; |
| 4374 | 4397 | ||
| 4398 | if (it->narrowed_begv) | ||
| 4399 | { | ||
| 4400 | record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); | ||
| 4401 | record_unwind_protect (unwind_narrowed_zv, Fpoint_max ()); | ||
| 4402 | SET_BUF_BEGV (current_buffer, it->narrowed_begv); | ||
| 4403 | SET_BUF_ZV (current_buffer, it->narrowed_zv); | ||
| 4404 | specbind (Qinhibit_widen, Qt); | ||
| 4405 | } | ||
| 4406 | |||
| 4375 | val = Vfontification_functions; | 4407 | val = Vfontification_functions; |
| 4376 | specbind (Qfontification_functions, Qnil); | 4408 | specbind (Qfontification_functions, Qnil); |
| 4377 | 4409 | ||