Speed up vertical-motion when screen coordinates are known
src/indent.c (Fvertical_motion): Accept an additional argument CUR-COL and use it as the starting screen coordinate. src/window.c (window_scroll_line_based, Fmove_to_window_line): All callers of vertical-motion changed. doc/lispref/positions.texi (Screen Lines): Update the documentation of vertical-motion to document the new additional argument.
This commit is contained in:
parent
af560cd6f1
commit
403cb178c7
5 changed files with 74 additions and 24 deletions
|
@ -1,3 +1,8 @@
|
|||
2015-02-09 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* positions.texi (Screen Lines): Update the documentation of
|
||||
vertical-motion to document the new additional argument.
|
||||
|
||||
2015-02-06 Nicolas Petton <nicolas@petton.fr>
|
||||
|
||||
* sequences.texi (Sequence Functions): Add documentation for
|
||||
|
|
|
@ -493,7 +493,7 @@ If you intend to use them heavily, Emacs provides caches which may
|
|||
improve the performance of your code. @xref{Truncation, cache-long-scans}.
|
||||
@end ignore
|
||||
|
||||
@defun vertical-motion count &optional window
|
||||
@defun vertical-motion count &optional window cur-col
|
||||
This function moves point to the start of the screen line @var{count}
|
||||
screen lines down from the screen line containing point. If @var{count}
|
||||
is negative, it moves up instead.
|
||||
|
@ -515,6 +515,14 @@ The window @var{window} is used for obtaining parameters such as the
|
|||
width, the horizontal scrolling, and the display table. But
|
||||
@code{vertical-motion} always operates on the current buffer, even if
|
||||
@var{window} currently displays some other buffer.
|
||||
|
||||
The optional argument @var{cur-col} specifies the current column when
|
||||
the function is called. This is the window-relative horizontal
|
||||
coordinate of point, measured in units of font width of the frame's
|
||||
default face. Providing it speeds up the function, especially in very
|
||||
long lines, because it doesn't have to go back in the buffer in order
|
||||
to determine the current column. Note that @var{cur-col} is also
|
||||
counted from the visual start of the line.
|
||||
@end defun
|
||||
|
||||
@defun count-screen-lines &optional beg end count-final-newline window
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2015-02-09 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* indent.c (Fvertical_motion): Accept an additional argument
|
||||
CUR-COL and use it as the starting screen coordinate.
|
||||
* window.c (window_scroll_line_based, Fmove_to_window_line): All
|
||||
callers of vertical-motion changed.
|
||||
|
||||
2015-02-09 Dima Kogan <dima@secretsauce.net>
|
||||
|
||||
* font.c (font_score): Remove unused variable assignment.
|
||||
|
|
55
src/indent.c
55
src/indent.c
|
@ -1928,7 +1928,7 @@ vmotion (register ptrdiff_t from, register ptrdiff_t from_byte,
|
|||
-1, hscroll, 0, w);
|
||||
}
|
||||
|
||||
DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0,
|
||||
DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 3, 0,
|
||||
doc: /* Move point to start of the screen line LINES lines down.
|
||||
If LINES is negative, this means moving up.
|
||||
|
||||
|
@ -1951,12 +1951,18 @@ is). If the line is scrolled horizontally, COLS is interpreted
|
|||
visually, i.e., as addition to the columns of text beyond the left
|
||||
edge of the window.
|
||||
|
||||
The optional third argument CUR-COL specifies the horizontal
|
||||
window-relative coordinate of point, in units of frame's canonical
|
||||
character width, where the function is invoked. If this argument is
|
||||
omitted or nil, the function will determine the point coordinate by
|
||||
going back to the beginning of the line.
|
||||
|
||||
`vertical-motion' always uses the current buffer,
|
||||
regardless of which buffer is displayed in WINDOW.
|
||||
This is consistent with other cursor motion functions
|
||||
and makes it possible to use `vertical-motion' in any buffer,
|
||||
whether or not it is currently displayed in some window. */)
|
||||
(Lisp_Object lines, Lisp_Object window)
|
||||
(Lisp_Object lines, Lisp_Object window, Lisp_Object cur_col)
|
||||
{
|
||||
struct it it;
|
||||
struct text_pos pt;
|
||||
|
@ -2006,6 +2012,22 @@ whether or not it is currently displayed in some window. */)
|
|||
bool disp_string_at_start_p = 0;
|
||||
ptrdiff_t nlines = XINT (lines);
|
||||
int vpos_init = 0;
|
||||
double start_col;
|
||||
int start_x;
|
||||
bool start_x_given = false;
|
||||
int to_x = -1;
|
||||
|
||||
if (!NILP (cur_col))
|
||||
{
|
||||
CHECK_NUMBER_OR_FLOAT (cur_col);
|
||||
start_col =
|
||||
INTEGERP (cur_col)
|
||||
? (double) XINT (cur_col)
|
||||
: XFLOAT_DATA (cur_col);
|
||||
start_x =
|
||||
(int)(start_col * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
|
||||
start_x_given = true;
|
||||
}
|
||||
|
||||
itdata = bidi_shelve_cache ();
|
||||
SET_TEXT_POS (pt, PT, PT_BYTE);
|
||||
|
@ -2042,11 +2064,19 @@ whether or not it is currently displayed in some window. */)
|
|||
it_overshoot_count =
|
||||
!(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH);
|
||||
|
||||
/* Scan from the start of the line containing PT. If we don't
|
||||
do this, we start moving with IT->current_x == 0, while PT is
|
||||
really at some x > 0. */
|
||||
reseat_at_previous_visible_line_start (&it);
|
||||
it.current_x = it.hpos = 0;
|
||||
if (start_x_given)
|
||||
{
|
||||
it.hpos = (int) start_col;
|
||||
it.current_x = start_x;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Scan from the start of the line containing PT. If we don't
|
||||
do this, we start moving with IT->current_x == 0, while PT is
|
||||
really at some x > 0. */
|
||||
reseat_at_previous_visible_line_start (&it);
|
||||
it.current_x = it.hpos = 0;
|
||||
}
|
||||
if (IT_CHARPOS (it) != PT)
|
||||
/* We used to temporarily disable selective display here; the
|
||||
comment said this is "so we don't move too far" (2005-01-19
|
||||
|
@ -2108,12 +2138,15 @@ whether or not it is currently displayed in some window. */)
|
|||
return the correct value to the caller. */
|
||||
vpos_init = -1;
|
||||
}
|
||||
if (!NILP (lcols))
|
||||
to_x = (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
|
||||
if (nlines <= 0)
|
||||
{
|
||||
it.vpos = vpos_init;
|
||||
/* Do this even if LINES is 0, so that we move back to the
|
||||
beginning of the current line as we ought. */
|
||||
if (nlines == 0 || IT_CHARPOS (it) > 0)
|
||||
if ((nlines < 0 && IT_CHARPOS (it) > 0)
|
||||
|| (nlines == 0 && !(start_x_given && start_x <= to_x)))
|
||||
move_it_by_lines (&it, max (PTRDIFF_MIN, nlines));
|
||||
}
|
||||
else if (overshoot_handled)
|
||||
|
@ -2153,11 +2186,7 @@ whether or not it is currently displayed in some window. */)
|
|||
was originally hscrolled, the goal column is interpreted as
|
||||
an addition to the hscroll amount. */
|
||||
if (!NILP (lcols))
|
||||
{
|
||||
int to_x = (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
|
||||
|
||||
move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
|
||||
}
|
||||
move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
|
||||
|
||||
SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
|
||||
bidi_unshelve_cache (itdata, 0);
|
||||
|
|
21
src/window.c
21
src/window.c
|
@ -5350,14 +5350,14 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
|
||||
if (NILP (tem))
|
||||
{
|
||||
Fvertical_motion (make_number (- (ht / 2)), window);
|
||||
Fvertical_motion (make_number (- (ht / 2)), window, Qnil);
|
||||
startpos = PT;
|
||||
startbyte = PT_BYTE;
|
||||
}
|
||||
|
||||
SET_PT_BOTH (startpos, startbyte);
|
||||
lose = n < 0 && PT == BEGV;
|
||||
Fvertical_motion (make_number (n), window);
|
||||
Fvertical_motion (make_number (n), window, Qnil);
|
||||
pos = PT;
|
||||
pos_byte = PT_BYTE;
|
||||
bolp = Fbolp ();
|
||||
|
@ -5389,7 +5389,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
&& (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
|
||||
{
|
||||
SET_PT_BOTH (pos, pos_byte);
|
||||
Fvertical_motion (original_pos, window);
|
||||
Fvertical_motion (original_pos, window, Qnil);
|
||||
}
|
||||
/* If we scrolled forward, put point enough lines down
|
||||
that it is outside the scroll margin. */
|
||||
|
@ -5400,7 +5400,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
if (this_scroll_margin > 0)
|
||||
{
|
||||
SET_PT_BOTH (pos, pos_byte);
|
||||
Fvertical_motion (make_number (this_scroll_margin), window);
|
||||
Fvertical_motion (make_number (this_scroll_margin), window, Qnil);
|
||||
top_margin = PT;
|
||||
}
|
||||
else
|
||||
|
@ -5412,7 +5412,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
else if (!NILP (Vscroll_preserve_screen_position))
|
||||
{
|
||||
SET_PT_BOTH (pos, pos_byte);
|
||||
Fvertical_motion (original_pos, window);
|
||||
Fvertical_motion (original_pos, window, Qnil);
|
||||
}
|
||||
else
|
||||
SET_PT (top_margin);
|
||||
|
@ -5424,7 +5424,8 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
/* If we scrolled backward, put point near the end of the window
|
||||
but not within the scroll margin. */
|
||||
SET_PT_BOTH (pos, pos_byte);
|
||||
tem = Fvertical_motion (make_number (ht - this_scroll_margin), window);
|
||||
tem = Fvertical_motion (make_number (ht - this_scroll_margin), window,
|
||||
Qnil);
|
||||
if (XFASTINT (tem) == ht - this_scroll_margin)
|
||||
bottom_margin = PT;
|
||||
else
|
||||
|
@ -5438,10 +5439,10 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
|
|||
if (!NILP (Vscroll_preserve_screen_position))
|
||||
{
|
||||
SET_PT_BOTH (pos, pos_byte);
|
||||
Fvertical_motion (original_pos, window);
|
||||
Fvertical_motion (original_pos, window, Qnil);
|
||||
}
|
||||
else
|
||||
Fvertical_motion (make_number (-1), window);
|
||||
Fvertical_motion (make_number (-1), window, Qnil);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5999,7 +6000,7 @@ zero means top of window, negative means relative to bottom of window. */)
|
|||
if (start < BEGV || start > ZV)
|
||||
{
|
||||
int height = window_internal_height (w);
|
||||
Fvertical_motion (make_number (- (height / 2)), window);
|
||||
Fvertical_motion (make_number (- (height / 2)), window, Qnil);
|
||||
set_marker_both (w->start, w->contents, PT, PT_BYTE);
|
||||
w->start_at_line_beg = !NILP (Fbolp ());
|
||||
w->force_start = 1;
|
||||
|
@ -6040,7 +6041,7 @@ zero means top of window, negative means relative to bottom of window. */)
|
|||
if (w->vscroll)
|
||||
XSETINT (arg, XINT (arg) + 1);
|
||||
|
||||
return Fvertical_motion (arg, window);
|
||||
return Fvertical_motion (arg, window, Qnil);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue