1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-12-02 08:22:22 +00:00

Improve locked narrowing around low-level hooks.

* src/buffer.c (syms_of_buffer): Two new variables,
'long-line-locked-narrowing-region-size' and
'long-line-locked-narrowing-bol-search-limit', to make the locked
narrowing around low-level hooks configurable.

Increase the default value of 'long-line-threshold'.  After
carefully considering the (few) bug reports about long line
optimizations, I concluded that the previous default value was too
low.

* src/xdisp.c (get_locked_narrowing_begv)
(get_locked_narrowing_zv): Two new functions.
(handle_fontified_prop, reseat): Use them.

* src/keyboard.c (safe_run_hooks_maybe_narrowed): Use them.

* src/dispextern.h (struct it): Add two new fields to store the
values returned by these functions.
Make them externally visible.

* src/editfns.c: (Fsave_restriction): Update docstring.
This commit is contained in:
Gregory Heytings 2022-11-26 14:09:41 +00:00
parent 16b8b0d1e0
commit 558084c7f7
5 changed files with 92 additions and 12 deletions

View File

@ -5882,7 +5882,40 @@ this threshold.
If nil, these display shortcuts will always remain disabled.
There is no reason to change that value except for debugging purposes. */);
XSETFASTINT (Vlong_line_threshold, 10000);
XSETFASTINT (Vlong_line_threshold, 50000);
DEFVAR_INT ("long-line-locked-narrowing-region-size",
long_line_locked_narrowing_region_size,
doc: /* Region size for locked narrowing in buffers with long lines.
This variable has effect only in buffers which contain one or more
lines whose length is above `long-line-threshold', which see. For
performance reasons, in such buffers, low-level hooks such as
`fontification-functions' or `post-command-hook' are executed on a
narrowed buffer, with a narrowing locked with `narrowing-lock'. This
variable specifies the size of the narrowed region around point.
To disable that narrowing, set this variable to 0.
There is no reason to change that value except for debugging purposes. */);
long_line_locked_narrowing_region_size = 500000;
DEFVAR_INT ("long-line-locked-narrowing-bol-search-limit",
long_line_locked_narrowing_bol_search_limit,
doc: /* Limit for beginning of line search in buffers with long lines.
This variable has effect only in buffers which contain one or more
lines whose length is above `long-line-threshold', which see. For
performance reasons, in such buffers, low-level hooks such as
`fontification-functions' or `post-command-hook' are executed on a
narrowed buffer, with a narrowing locked with `narrowing-lock'. The
variable `long-line-locked-narrowing-region-size' specifies the size
of the narrowed region around point. This variable, which should be a
small integer, specifies the number of characters by which that region
can be extended backwards to start it at the beginning of a line.
There is no reason to change that value except for debugging purposes. */);
long_line_locked_narrowing_bol_search_limit = 128;
DEFVAR_INT ("large-hscroll-threshold", large_hscroll_threshold,
doc: /* Horizontal scroll of truncated lines above which to use redisplay shortcuts.

View File

@ -2342,6 +2342,14 @@ struct it
optimize display. */
ptrdiff_t narrowed_zv;
/* Begin position of the buffer for the locked narrowing around
low-level hooks. */
ptrdiff_t locked_narrowing_begv;
/* End position of the buffer for the locked narrowing around
low-level hooks. */
ptrdiff_t locked_narrowing_zv;
/* C string to iterate over. Non-null means get characters from
this string, otherwise characters are read from current_buffer
or it->string. */
@ -3405,6 +3413,8 @@ void init_iterator (struct it *, struct window *, ptrdiff_t,
ptrdiff_t get_narrowed_begv (struct window *, ptrdiff_t);
ptrdiff_t get_narrowed_zv (struct window *, ptrdiff_t);
ptrdiff_t get_closer_narrowed_begv (struct window *, ptrdiff_t);
ptrdiff_t get_locked_narrowing_begv (ptrdiff_t);
ptrdiff_t get_locked_narrowing_zv (ptrdiff_t);
void init_iterator_to_row_start (struct it *, struct window *,
struct glyph_row *);
void start_display (struct it *, struct window *, struct text_pos);

View File

@ -2659,7 +2659,7 @@ DEFUN ("delete-and-extract-region", Fdelete_and_extract_region,
the (uninterned) Qoutermost_narrowing tag and records the narrowing
bounds that were set by the user and that are visible on display.
This alist is used internally by narrow-to-region, widen,
narrowing-lock and narrowing-unlock. */
narrowing-lock, narrowing-unlock and save-restriction. */
static Lisp_Object narrowing_locks;
/* Retrieve one of the BEGV/ZV bounds of a narrowing in BUF from the
@ -3061,11 +3061,12 @@ DEFUN ("save-restriction", Fsave_restriction, Ssave_restriction, 0, UNEVALLED, 0
doc: /* Execute BODY, saving and restoring current buffer's restrictions.
The buffer's restrictions make parts of the beginning and end invisible.
\(They are set up with `narrow-to-region' and eliminated with `widen'.)
This special form, `save-restriction', saves the current buffer's restrictions
when it is entered, and restores them when it is exited.
This special form, `save-restriction', saves the current buffer's
restrictions, as well as their locks if they have been locked with
`narrowing-lock', when it is entered, and restores them when it is exited.
So any `narrow-to-region' within BODY lasts only until the end of the form.
The old restrictions settings are restored
even in case of abnormal exit (throw or error).
The old restrictions settings are restored even in case of abnormal exit
\(throw or error).
The value returned is the value of the last form in BODY.

View File

@ -1911,8 +1911,8 @@ safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
specbind (Qinhibit_quit, Qt);
if (current_buffer->long_line_optimizations_p)
narrow_to_region_locked (make_fixnum (get_narrowed_begv (w, PT)),
make_fixnum (get_narrowed_zv (w, PT)),
narrow_to_region_locked (make_fixnum (get_locked_narrowing_begv (PT)),
make_fixnum (get_locked_narrowing_zv (PT)),
hook);
run_hook_with_args (2, ((Lisp_Object []) {hook, hook}),

View File

@ -3533,6 +3533,34 @@ get_closer_narrowed_begv (struct window *w, ptrdiff_t pos)
return max ((pos / len - 1) * len, BEGV);
}
ptrdiff_t
get_locked_narrowing_begv (ptrdiff_t pos)
{
if (long_line_locked_narrowing_region_size == 0)
return BEGV;
int begv;
int len = long_line_locked_narrowing_region_size / 2;
begv = max (pos - len, BEGV);
int limit = long_line_locked_narrowing_bol_search_limit;
while (limit)
{
if (begv == BEGV || FETCH_BYTE (CHAR_TO_BYTE (begv) - 1) == '\n')
return begv;
begv--;
limit--;
}
return begv;
}
ptrdiff_t
get_locked_narrowing_zv (ptrdiff_t pos)
{
if (long_line_locked_narrowing_region_size == 0)
return ZV;
int len = long_line_locked_narrowing_region_size / 2;
return min (pos + len, ZV);
}
static void
unwind_narrowed_begv (Lisp_Object point_min)
{
@ -4368,13 +4396,13 @@ handle_fontified_prop (struct it *it)
if (current_buffer->long_line_optimizations_p)
{
ptrdiff_t begv = it->narrowed_begv;
ptrdiff_t zv = it->narrowed_zv;
ptrdiff_t begv = it->locked_narrowing_begv;
ptrdiff_t zv = it->locked_narrowing_zv;
ptrdiff_t charpos = IT_CHARPOS (*it);
if (charpos < begv || charpos > zv)
{
begv = get_narrowed_begv (it->w, charpos);
zv = get_narrowed_zv (it->w, charpos);
begv = get_locked_narrowing_begv (charpos);
zv = get_locked_narrowing_zv (charpos);
}
narrow_to_region_locked (make_fixnum (begv), make_fixnum (zv),
Qfontification_functions);
@ -7435,12 +7463,20 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
{
it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w));
it->narrowed_zv = get_narrowed_zv (it->w, window_point (it->w));
it->locked_narrowing_begv
= get_locked_narrowing_begv (window_point (it->w));
it->locked_narrowing_zv
= get_locked_narrowing_zv (window_point (it->w));
}
else if ((pos.charpos < it->narrowed_begv || pos.charpos > it->narrowed_zv)
&& (!redisplaying_p || it->line_wrap == TRUNCATE))
{
it->narrowed_begv = get_narrowed_begv (it->w, pos.charpos);
it->narrowed_zv = get_narrowed_zv (it->w, pos.charpos);
it->locked_narrowing_begv
= get_locked_narrowing_begv (window_point (it->w));
it->locked_narrowing_zv
= get_locked_narrowing_zv (window_point (it->w));
}
}