diff options
author | Eli Zaretskii <eliz@gnu.org> | 2015-02-09 18:24:46 +0200 |
---|---|---|
committer | Eli Zaretskii <eliz@gnu.org> | 2015-02-09 18:24:46 +0200 |
commit | 403cb178c75a80603dbd8ed23e342d2109645401 (patch) | |
tree | 815315bef8212ed239805f13089612ebcef78a82 /src/indent.c | |
parent | af560cd6f15e7cc7e42bff5b3c802b9d1d1640b5 (diff) | |
download | emacs-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.c | 55 |
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); |