diff options
author | Gregory Heytings <gregory@heytings.org> | 2022-07-22 10:03:13 +0000 |
---|---|---|
committer | Gregory Heytings <gregory@heytings.org> | 2022-07-22 12:06:31 +0200 |
commit | 874e2525035d45efa6fa374a2ebec3740ecc1457 (patch) | |
tree | 059221aee889a88f558802014c5680017eaec1d0 /src | |
parent | 616da8fa8efa9023f56fa731072d877e2150afbc (diff) | |
download | emacs-874e2525035d45efa6fa374a2ebec3740ecc1457.tar.gz emacs-874e2525035d45efa6fa374a2ebec3740ecc1457.tar.bz2 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 optimize display (see the SET_WITH_NARROWED_BEGV macro). */ ptrdiff_t narrowed_begv; + /* Alternate end position of the buffer that may be used to + optimize display. */ + ptrdiff_t narrowed_zv; + /* C string to iterate over. Non-null means get characters from this string, otherwise characters are read from current_buffer or it->string. */ @@ -3401,6 +3405,7 @@ void redisplay_preserve_echo_area (int); void init_iterator (struct it *, struct window *, ptrdiff_t, ptrdiff_t, struct glyph_row *, enum face_id); ptrdiff_t get_narrowed_begv (struct window *w); +ptrdiff_t get_narrowed_zv (struct window *w); void init_iterator_to_row_start (struct it *, struct window *, struct glyph_row *); 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, "", This allows the buffer's full text to be seen and edited. */) (void) { + if (!NILP (Vinhibit_widen)) + return Qnil; if (BEG != BEGV || Z != ZV) current_buffer->clip_changed = 1; BEGV = BEG; @@ -4457,6 +4459,7 @@ syms_of_editfns (void) DEFSYM (Qbuffer_access_fontify_functions, "buffer-access-fontify-functions"); DEFSYM (Qwall, "wall"); DEFSYM (Qpropertize, "propertize"); + DEFSYM (Qinhibit_widen, "inhibit-widen"); DEFVAR_LISP ("inhibit-field-text-motion", Vinhibit_field_text_motion, 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 it to be non-nil. */); binary_as_unsigned = false; + DEFVAR_LISP ("inhibit-widen", Vinhibit_widen, + doc: /* Non-nil inhibits the `widen' function. + +Do NOT set this globally to a non-nil value, as doing that will +disable the `widen' function everywhere, including the \\[widen\] +command. This variable is intended to be let-bound around code +that needs to disable `widen' temporarily. */); + Vinhibit_widen = Qnil; + defsubr (&Spropertize); defsubr (&Schar_equal); 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, } if (current_buffer->long_line_optimizations_p) - it->narrowed_begv = get_narrowed_begv (w); + { + it->narrowed_begv = get_narrowed_begv (w); + it->narrowed_zv = get_narrowed_zv (w); + } /* If a buffer position was specified, set the iterator there, getting overlays and face properties from that position. */ @@ -3494,29 +3497,49 @@ init_iterator (struct it *it, struct window *w, CHECK_IT (it); } -/* Compute a suitable alternate value for BEGV that may be used +/* Compute a suitable alternate value for BEGV and ZV that may be used temporarily to optimize display if the buffer in window W contains long lines. */ -ptrdiff_t -get_narrowed_begv (struct window *w) +static int +get_narrowed_len (struct window *w) { - int len, fact; ptrdiff_t begv; + int fact; /* In a character-only terminal, only one font size is used, so we can use a smaller factor. */ fact = EQ (Fterminal_live_p (Qnil), Qt) ? 2 : 3; - len = fact * (window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) * - window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)); + return fact * (window_body_width (w, WINDOW_BODY_IN_CANONICAL_CHARS) * + window_body_height (w, WINDOW_BODY_IN_CANONICAL_CHARS)); +} + +ptrdiff_t +get_narrowed_begv (struct window *w) +{ + int len = get_narrowed_len (w); + ptrdiff_t begv; begv = max ((window_point (w) / len - 1) * len, BEGV); return begv == BEGV ? 0 : begv; } +ptrdiff_t +get_narrowed_zv (struct window *w) +{ + int len = get_narrowed_len (w); + return min ((window_point (w) / len + 1) * len, ZV); +} + static void unwind_narrowed_begv (Lisp_Object point_min) { SET_BUF_BEGV (current_buffer, XFIXNUM (point_min)); } +static void +unwind_narrowed_zv (Lisp_Object point_max) +{ + SET_BUF_ZV (current_buffer, XFIXNUM (point_max)); +} + /* Set DST to EXPR. When IT indicates that BEGV should temporarily be updated to optimize display, evaluate EXPR with an updated BEGV. */ @@ -4372,6 +4395,15 @@ handle_fontified_prop (struct it *it) bool old_clip_changed = current_buffer->clip_changed; bool saved_inhibit_flag = it->f->inhibit_clear_image_cache; + if (it->narrowed_begv) + { + record_unwind_protect (unwind_narrowed_begv, Fpoint_min ()); + record_unwind_protect (unwind_narrowed_zv, Fpoint_max ()); + SET_BUF_BEGV (current_buffer, it->narrowed_begv); + SET_BUF_ZV (current_buffer, it->narrowed_zv); + specbind (Qinhibit_widen, Qt); + } + val = Vfontification_functions; specbind (Qfontification_functions, Qnil); |