mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-13 06:50:39 -08:00
Merge branch 'feature/long-lines-improvements'
This commit is contained in:
commit
5a79bb2aed
6 changed files with 88 additions and 30 deletions
|
|
@ -6431,12 +6431,15 @@ will run for `clone-indirect-buffer' calls as well. */);
|
|||
|
||||
DEFVAR_LISP ("long-line-threshold", Vlong_line_threshold,
|
||||
doc: /* Line length above which to use redisplay shortcuts.
|
||||
|
||||
The value should be a positive integer or nil.
|
||||
If the value is an integer, shortcuts in the display code intended
|
||||
to speed up redisplay for long lines will automatically be enabled
|
||||
in buffers which contain one or more lines whose length is above
|
||||
this threshold.
|
||||
If nil, these display shortcuts will always remain disabled. */);
|
||||
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);
|
||||
|
||||
defsubr (&Sbuffer_live_p);
|
||||
|
|
|
|||
|
|
@ -1021,7 +1021,11 @@ composition_compute_stop_pos (struct composition_it *cmp_it, ptrdiff_t charpos,
|
|||
/* But we don't know where to stop the searching. */
|
||||
endpos = NILP (string) ? BEGV - 1 : -1;
|
||||
/* Usually we don't reach ENDPOS because we stop searching
|
||||
at an uncomposable character (NL, LRE, etc). */
|
||||
at an uncomposable character (NL, LRE, etc). In buffers
|
||||
with long lines, however, NL might be far away, so
|
||||
pretend that the buffer is smaller. */
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
endpos = get_closer_narrowed_begv (cmp_it->parent_it->w, charpos);
|
||||
}
|
||||
}
|
||||
cmp_it->id = -1;
|
||||
|
|
@ -1580,7 +1584,6 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
|
|||
Lisp_Object window;
|
||||
struct window *w;
|
||||
bool need_adjustment = 0;
|
||||
ptrdiff_t narrowed_begv;
|
||||
|
||||
window = Fget_buffer_window (Fcurrent_buffer (), Qnil);
|
||||
if (NILP (window))
|
||||
|
|
@ -1597,11 +1600,14 @@ find_automatic_composition (ptrdiff_t pos, ptrdiff_t limit, ptrdiff_t backlim,
|
|||
}
|
||||
else
|
||||
head = backlim;
|
||||
/* In buffers with very long lines, this function becomes very
|
||||
slow. Pretend that the buffer is narrowed to make it fast. */
|
||||
narrowed_begv = get_narrowed_begv (w, window_point (w));
|
||||
if (narrowed_begv && pos > narrowed_begv)
|
||||
head = narrowed_begv;
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
{
|
||||
/* In buffers with very long lines, this function becomes very
|
||||
slow. Pretend that the buffer is narrowed to make it fast. */
|
||||
ptrdiff_t begv = get_closer_narrowed_begv (w, window_point (w));
|
||||
if (pos > begv)
|
||||
head = begv;
|
||||
}
|
||||
tail = ZV;
|
||||
stop = GPT;
|
||||
cur.pos_byte = CHAR_TO_BYTE (cur.pos);
|
||||
|
|
|
|||
|
|
@ -2287,6 +2287,8 @@ struct composition_it
|
|||
reverse order, and thus the grapheme clusters must be rendered
|
||||
from the last to the first. */
|
||||
bool reversed_p;
|
||||
/* Parent iterator. */
|
||||
struct it *parent_it;
|
||||
|
||||
/** The following members contain information about the current
|
||||
grapheme cluster. */
|
||||
|
|
|
|||
|
|
@ -1295,7 +1295,8 @@ command_loop_1 (void)
|
|||
/* Note that the value cell will never directly contain nil
|
||||
if the symbol is a local variable. */
|
||||
if (!NILP (Vpost_command_hook) && !NILP (Vrun_hooks))
|
||||
safe_run_hooks (Qpost_command_hook);
|
||||
safe_run_hooks_maybe_narrowed (Qpost_command_hook,
|
||||
XWINDOW (selected_window));
|
||||
|
||||
/* If displaying a message, resize the echo area window to fit
|
||||
that message's size exactly. */
|
||||
|
|
@ -1461,7 +1462,9 @@ command_loop_1 (void)
|
|||
}
|
||||
Vthis_command = cmd;
|
||||
Vreal_this_command = cmd;
|
||||
safe_run_hooks (Qpre_command_hook);
|
||||
|
||||
safe_run_hooks_maybe_narrowed (Qpre_command_hook,
|
||||
XWINDOW (selected_window));
|
||||
|
||||
already_adjusted = 0;
|
||||
|
||||
|
|
@ -1513,7 +1516,8 @@ command_loop_1 (void)
|
|||
}
|
||||
kset_last_prefix_arg (current_kboard, Vcurrent_prefix_arg);
|
||||
|
||||
safe_run_hooks (Qpost_command_hook);
|
||||
safe_run_hooks_maybe_narrowed (Qpost_command_hook,
|
||||
XWINDOW (selected_window));
|
||||
|
||||
/* If displaying a message, resize the echo area window to fit
|
||||
that message's size exactly. Do this only if the echo area
|
||||
|
|
@ -1895,6 +1899,22 @@ safe_run_hooks (Lisp_Object hook)
|
|||
unbind_to (count, Qnil);
|
||||
}
|
||||
|
||||
void
|
||||
safe_run_hooks_maybe_narrowed (Lisp_Object hook, struct window *w)
|
||||
{
|
||||
specpdl_ref count = SPECPDL_INDEX ();
|
||||
|
||||
specbind (Qinhibit_quit, Qt);
|
||||
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
narrow_to_region_internal (make_fixnum (get_narrowed_begv (w, PT)),
|
||||
make_fixnum (get_narrowed_zv (w, PT)),
|
||||
true);
|
||||
|
||||
run_hook_with_args (2, ((Lisp_Object []) {hook, hook}), safe_run_hook_funcall);
|
||||
unbind_to (count, Qnil);
|
||||
}
|
||||
|
||||
|
||||
/* Nonzero means polling for input is temporarily suppressed. */
|
||||
|
||||
|
|
@ -12622,23 +12642,39 @@ Buffer modification stores t in this variable. */);
|
|||
|
||||
DEFVAR_LISP ("pre-command-hook", Vpre_command_hook,
|
||||
doc: /* Normal hook run before each command is executed.
|
||||
If an unhandled error happens in running this hook,
|
||||
the function in which the error occurred is unconditionally removed, since
|
||||
otherwise the error might happen repeatedly and make Emacs nonfunctional.
|
||||
|
||||
If an unhandled error happens in running this hook, the function in
|
||||
which the error occurred is unconditionally removed, since otherwise
|
||||
the error might happen repeatedly and make Emacs nonfunctional.
|
||||
|
||||
Note that, when the current buffer contains one or more lines whose
|
||||
length is above `long-line-threshold', these hook functions are called
|
||||
with the buffer narrowed to a small portion around point, and the
|
||||
narrowing is locked (see `narrow-to-region'), so that these hook
|
||||
functions cannot use `widen' to gain access to other portions of
|
||||
buffer text.
|
||||
|
||||
See also `post-command-hook'. */);
|
||||
Vpre_command_hook = Qnil;
|
||||
|
||||
DEFVAR_LISP ("post-command-hook", Vpost_command_hook,
|
||||
doc: /* Normal hook run after each command is executed.
|
||||
If an unhandled error happens in running this hook,
|
||||
the function in which the error occurred is unconditionally removed, since
|
||||
otherwise the error might happen repeatedly and make Emacs nonfunctional.
|
||||
|
||||
If an unhandled error happens in running this hook, the function in
|
||||
which the error occurred is unconditionally removed, since otherwise
|
||||
the error might happen repeatedly and make Emacs nonfunctional.
|
||||
|
||||
It is a bad idea to use this hook for expensive processing. If
|
||||
unavoidable, wrap your code in `(while-no-input (redisplay) CODE)' to
|
||||
avoid making Emacs unresponsive while the user types.
|
||||
|
||||
Note that, when the current buffer contains one or more lines whose
|
||||
length is above `long-line-threshold', these hook functions are called
|
||||
with the buffer narrowed to a small portion around point, and the
|
||||
narrowing is locked (see `narrow-to-region'), so that these hook
|
||||
functions cannot use `widen' to gain access to other portions of
|
||||
buffer text.
|
||||
|
||||
See also `pre-command-hook'. */);
|
||||
Vpost_command_hook = Qnil;
|
||||
|
||||
|
|
|
|||
|
|
@ -4830,6 +4830,7 @@ extern bool detect_input_pending (void);
|
|||
extern bool detect_input_pending_ignore_squeezables (void);
|
||||
extern bool detect_input_pending_run_timers (bool);
|
||||
extern void safe_run_hooks (Lisp_Object);
|
||||
extern void safe_run_hooks_maybe_narrowed (Lisp_Object, struct window *);
|
||||
extern void cmd_error_internal (Lisp_Object, const char *);
|
||||
extern Lisp_Object command_loop_2 (Lisp_Object);
|
||||
extern Lisp_Object read_menu_command (void);
|
||||
|
|
|
|||
36
src/xdisp.c
36
src/xdisp.c
|
|
@ -3229,6 +3229,7 @@ init_iterator (struct it *it, struct window *w,
|
|||
it->f = XFRAME (w->frame);
|
||||
|
||||
it->cmp_it.id = -1;
|
||||
it->cmp_it.parent_it = it;
|
||||
|
||||
if (max_redisplay_ticks > 0)
|
||||
update_redisplay_ticks (0, w);
|
||||
|
|
@ -3413,12 +3414,6 @@ init_iterator (struct it *it, struct window *w,
|
|||
}
|
||||
}
|
||||
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
{
|
||||
it->narrowed_begv = get_narrowed_begv (w, window_point (w));
|
||||
it->narrowed_zv = get_narrowed_zv (w, window_point (w));
|
||||
}
|
||||
|
||||
/* If a buffer position was specified, set the iterator there,
|
||||
getting overlays and face properties from that position. */
|
||||
if (charpos >= BUF_BEG (current_buffer))
|
||||
|
|
@ -3478,6 +3473,9 @@ init_iterator (struct it *it, struct window *w,
|
|||
&it->bidi_it);
|
||||
}
|
||||
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
it->narrowed_begv = 0;
|
||||
|
||||
/* Compute faces etc. */
|
||||
reseat (it, it->current.pos, true);
|
||||
}
|
||||
|
|
@ -3510,9 +3508,7 @@ ptrdiff_t
|
|||
get_narrowed_begv (struct window *w, ptrdiff_t pos)
|
||||
{
|
||||
int len = get_narrowed_len (w);
|
||||
ptrdiff_t begv;
|
||||
begv = max ((pos / len - 1) * len, BEGV);
|
||||
return begv == BEGV ? 0 : begv;
|
||||
return max ((pos / len - 1) * len, BEGV);
|
||||
}
|
||||
|
||||
ptrdiff_t
|
||||
|
|
@ -4397,13 +4393,12 @@ handle_fontified_prop (struct it *it)
|
|||
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
{
|
||||
ptrdiff_t begv = it->narrowed_begv ? it->narrowed_begv : BEGV;
|
||||
ptrdiff_t begv = it->narrowed_begv;
|
||||
ptrdiff_t zv = it->narrowed_zv;
|
||||
ptrdiff_t charpos = IT_CHARPOS (*it);
|
||||
if (charpos < begv || charpos > zv)
|
||||
{
|
||||
begv = get_narrowed_begv (it->w, charpos);
|
||||
if (!begv) begv = BEGV;
|
||||
zv = get_narrowed_zv (it->w, charpos);
|
||||
}
|
||||
narrow_to_region_internal (make_fixnum (begv), make_fixnum (zv), true);
|
||||
|
|
@ -7533,6 +7528,21 @@ reseat (struct it *it, struct text_pos pos, bool force_p)
|
|||
|
||||
reseat_1 (it, pos, false);
|
||||
|
||||
if (current_buffer->long_line_optimizations_p)
|
||||
{
|
||||
if (!it->narrowed_begv)
|
||||
{
|
||||
it->narrowed_begv = get_narrowed_begv (it->w, window_point (it->w));
|
||||
it->narrowed_zv = get_narrowed_zv (it->w, 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine where to check text properties. Avoid doing it
|
||||
where possible because text property lookup is very expensive. */
|
||||
if (force_p
|
||||
|
|
@ -8838,7 +8848,7 @@ get_visually_first_element (struct it *it)
|
|||
|
||||
SET_WITH_NARROWED_BEGV (it, bob,
|
||||
string_p ? 0 :
|
||||
IT_BYTEPOS (*it) < BEGV ? obegv : BEGV,
|
||||
IT_CHARPOS (*it) < BEGV ? obegv : BEGV,
|
||||
it->narrowed_begv);
|
||||
|
||||
if (STRINGP (it->string))
|
||||
|
|
@ -10773,7 +10783,7 @@ move_it_vertically_backward (struct it *it, int dy)
|
|||
dec_both (&cp, &bp);
|
||||
SET_WITH_NARROWED_BEGV (it, cp,
|
||||
find_newline_no_quit (cp, bp, -1, NULL),
|
||||
it->narrowed_begv);
|
||||
get_closer_narrowed_begv (it->w, IT_CHARPOS (*it)));
|
||||
move_it_to (it, cp, -1, -1, -1, MOVE_TO_POS);
|
||||
}
|
||||
bidi_unshelve_cache (it3data, true);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue