summaryrefslogtreecommitdiff
path: root/src/indent.c
diff options
context:
space:
mode:
authorEli Zaretskii <eliz@gnu.org>2015-02-09 18:24:46 +0200
committerEli Zaretskii <eliz@gnu.org>2015-02-09 18:24:46 +0200
commit403cb178c75a80603dbd8ed23e342d2109645401 (patch)
tree815315bef8212ed239805f13089612ebcef78a82 /src/indent.c
parentaf560cd6f15e7cc7e42bff5b3c802b9d1d1640b5 (diff)
downloademacs-403cb178c75a80603dbd8ed23e342d2109645401.tar.gz
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.
Diffstat (limited to 'src/indent.c')
-rw-r--r--src/indent.c55
1 files changed, 42 insertions, 13 deletions
diff --git a/src/indent.c b/src/indent.c
index 8660400e1ce..f0aea002fd2 100644
--- a/src/indent.c
+++ b/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);