aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2015-02-09 18:24:46 +0200
committerEli Zaretskii2015-02-09 18:24:46 +0200
commit403cb178c75a80603dbd8ed23e342d2109645401 (patch)
tree815315bef8212ed239805f13089612ebcef78a82
parentaf560cd6f15e7cc7e42bff5b3c802b9d1d1640b5 (diff)
downloademacs-403cb178c75a80603dbd8ed23e342d2109645401.tar.gz
emacs-403cb178c75a80603dbd8ed23e342d2109645401.zip
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.
-rw-r--r--doc/lispref/ChangeLog5
-rw-r--r--doc/lispref/positions.texi10
-rw-r--r--src/ChangeLog7
-rw-r--r--src/indent.c55
-rw-r--r--src/window.c21
5 files changed, 74 insertions, 24 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 3fe3d6fd6a0..0c76a6b8b34 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,8 @@
12015-02-09 Eli Zaretskii <eliz@gnu.org>
2
3 * positions.texi (Screen Lines): Update the documentation of
4 vertical-motion to document the new additional argument.
5
12015-02-06 Nicolas Petton <nicolas@petton.fr> 62015-02-06 Nicolas Petton <nicolas@petton.fr>
2 7
3 * sequences.texi (Sequence Functions): Add documentation for 8 * sequences.texi (Sequence Functions): Add documentation for
diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi
index 317b9d64a5c..b74116ebf1d 100644
--- a/doc/lispref/positions.texi
+++ b/doc/lispref/positions.texi
@@ -493,7 +493,7 @@ If you intend to use them heavily, Emacs provides caches which may
493improve the performance of your code. @xref{Truncation, cache-long-scans}. 493improve the performance of your code. @xref{Truncation, cache-long-scans}.
494@end ignore 494@end ignore
495 495
496@defun vertical-motion count &optional window 496@defun vertical-motion count &optional window cur-col
497This function moves point to the start of the screen line @var{count} 497This function moves point to the start of the screen line @var{count}
498screen lines down from the screen line containing point. If @var{count} 498screen lines down from the screen line containing point. If @var{count}
499is negative, it moves up instead. 499is negative, it moves up instead.
@@ -515,6 +515,14 @@ The window @var{window} is used for obtaining parameters such as the
515width, the horizontal scrolling, and the display table. But 515width, the horizontal scrolling, and the display table. But
516@code{vertical-motion} always operates on the current buffer, even if 516@code{vertical-motion} always operates on the current buffer, even if
517@var{window} currently displays some other buffer. 517@var{window} currently displays some other buffer.
518
519The optional argument @var{cur-col} specifies the current column when
520the function is called. This is the window-relative horizontal
521coordinate of point, measured in units of font width of the frame's
522default face. Providing it speeds up the function, especially in very
523long lines, because it doesn't have to go back in the buffer in order
524to determine the current column. Note that @var{cur-col} is also
525counted from the visual start of the line.
518@end defun 526@end defun
519 527
520@defun count-screen-lines &optional beg end count-final-newline window 528@defun count-screen-lines &optional beg end count-final-newline window
diff --git a/src/ChangeLog b/src/ChangeLog
index 2a702a29a7d..4afcdcf0711 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12015-02-09 Eli Zaretskii <eliz@gnu.org>
2
3 * indent.c (Fvertical_motion): Accept an additional argument
4 CUR-COL and use it as the starting screen coordinate.
5 * window.c (window_scroll_line_based, Fmove_to_window_line): All
6 callers of vertical-motion changed.
7
12015-02-09 Dima Kogan <dima@secretsauce.net> 82015-02-09 Dima Kogan <dima@secretsauce.net>
2 9
3 * font.c (font_score): Remove unused variable assignment. 10 * font.c (font_score): Remove unused variable assignment.
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,
1928 -1, hscroll, 0, w); 1928 -1, hscroll, 0, w);
1929} 1929}
1930 1930
1931DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0, 1931DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 3, 0,
1932 doc: /* Move point to start of the screen line LINES lines down. 1932 doc: /* Move point to start of the screen line LINES lines down.
1933If LINES is negative, this means moving up. 1933If LINES is negative, this means moving up.
1934 1934
@@ -1951,12 +1951,18 @@ is). If the line is scrolled horizontally, COLS is interpreted
1951visually, i.e., as addition to the columns of text beyond the left 1951visually, i.e., as addition to the columns of text beyond the left
1952edge of the window. 1952edge of the window.
1953 1953
1954The optional third argument CUR-COL specifies the horizontal
1955window-relative coordinate of point, in units of frame's canonical
1956character width, where the function is invoked. If this argument is
1957omitted or nil, the function will determine the point coordinate by
1958going back to the beginning of the line.
1959
1954`vertical-motion' always uses the current buffer, 1960`vertical-motion' always uses the current buffer,
1955regardless of which buffer is displayed in WINDOW. 1961regardless of which buffer is displayed in WINDOW.
1956This is consistent with other cursor motion functions 1962This is consistent with other cursor motion functions
1957and makes it possible to use `vertical-motion' in any buffer, 1963and makes it possible to use `vertical-motion' in any buffer,
1958whether or not it is currently displayed in some window. */) 1964whether or not it is currently displayed in some window. */)
1959 (Lisp_Object lines, Lisp_Object window) 1965 (Lisp_Object lines, Lisp_Object window, Lisp_Object cur_col)
1960{ 1966{
1961 struct it it; 1967 struct it it;
1962 struct text_pos pt; 1968 struct text_pos pt;
@@ -2006,6 +2012,22 @@ whether or not it is currently displayed in some window. */)
2006 bool disp_string_at_start_p = 0; 2012 bool disp_string_at_start_p = 0;
2007 ptrdiff_t nlines = XINT (lines); 2013 ptrdiff_t nlines = XINT (lines);
2008 int vpos_init = 0; 2014 int vpos_init = 0;
2015 double start_col;
2016 int start_x;
2017 bool start_x_given = false;
2018 int to_x = -1;
2019
2020 if (!NILP (cur_col))
2021 {
2022 CHECK_NUMBER_OR_FLOAT (cur_col);
2023 start_col =
2024 INTEGERP (cur_col)
2025 ? (double) XINT (cur_col)
2026 : XFLOAT_DATA (cur_col);
2027 start_x =
2028 (int)(start_col * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
2029 start_x_given = true;
2030 }
2009 2031
2010 itdata = bidi_shelve_cache (); 2032 itdata = bidi_shelve_cache ();
2011 SET_TEXT_POS (pt, PT, PT_BYTE); 2033 SET_TEXT_POS (pt, PT, PT_BYTE);
@@ -2042,11 +2064,19 @@ whether or not it is currently displayed in some window. */)
2042 it_overshoot_count = 2064 it_overshoot_count =
2043 !(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH); 2065 !(it.method == GET_FROM_IMAGE || it.method == GET_FROM_STRETCH);
2044 2066
2045 /* Scan from the start of the line containing PT. If we don't 2067 if (start_x_given)
2046 do this, we start moving with IT->current_x == 0, while PT is 2068 {
2047 really at some x > 0. */ 2069 it.hpos = (int) start_col;
2048 reseat_at_previous_visible_line_start (&it); 2070 it.current_x = start_x;
2049 it.current_x = it.hpos = 0; 2071 }
2072 else
2073 {
2074 /* Scan from the start of the line containing PT. If we don't
2075 do this, we start moving with IT->current_x == 0, while PT is
2076 really at some x > 0. */
2077 reseat_at_previous_visible_line_start (&it);
2078 it.current_x = it.hpos = 0;
2079 }
2050 if (IT_CHARPOS (it) != PT) 2080 if (IT_CHARPOS (it) != PT)
2051 /* We used to temporarily disable selective display here; the 2081 /* We used to temporarily disable selective display here; the
2052 comment said this is "so we don't move too far" (2005-01-19 2082 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. */)
2108 return the correct value to the caller. */ 2138 return the correct value to the caller. */
2109 vpos_init = -1; 2139 vpos_init = -1;
2110 } 2140 }
2141 if (!NILP (lcols))
2142 to_x = (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
2111 if (nlines <= 0) 2143 if (nlines <= 0)
2112 { 2144 {
2113 it.vpos = vpos_init; 2145 it.vpos = vpos_init;
2114 /* Do this even if LINES is 0, so that we move back to the 2146 /* Do this even if LINES is 0, so that we move back to the
2115 beginning of the current line as we ought. */ 2147 beginning of the current line as we ought. */
2116 if (nlines == 0 || IT_CHARPOS (it) > 0) 2148 if ((nlines < 0 && IT_CHARPOS (it) > 0)
2149 || (nlines == 0 && !(start_x_given && start_x <= to_x)))
2117 move_it_by_lines (&it, max (PTRDIFF_MIN, nlines)); 2150 move_it_by_lines (&it, max (PTRDIFF_MIN, nlines));
2118 } 2151 }
2119 else if (overshoot_handled) 2152 else if (overshoot_handled)
@@ -2153,11 +2186,7 @@ whether or not it is currently displayed in some window. */)
2153 was originally hscrolled, the goal column is interpreted as 2186 was originally hscrolled, the goal column is interpreted as
2154 an addition to the hscroll amount. */ 2187 an addition to the hscroll amount. */
2155 if (!NILP (lcols)) 2188 if (!NILP (lcols))
2156 { 2189 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
2157 int to_x = (int)(cols * FRAME_COLUMN_WIDTH (XFRAME (w->frame)) + 0.5);
2158
2159 move_it_in_display_line (&it, ZV, first_x + to_x, MOVE_TO_X);
2160 }
2161 2190
2162 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it)); 2191 SET_PT_BOTH (IT_CHARPOS (it), IT_BYTEPOS (it));
2163 bidi_unshelve_cache (itdata, 0); 2192 bidi_unshelve_cache (itdata, 0);
diff --git a/src/window.c b/src/window.c
index 293140041a9..d59616d0545 100644
--- a/src/window.c
+++ b/src/window.c
@@ -5350,14 +5350,14 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5350 5350
5351 if (NILP (tem)) 5351 if (NILP (tem))
5352 { 5352 {
5353 Fvertical_motion (make_number (- (ht / 2)), window); 5353 Fvertical_motion (make_number (- (ht / 2)), window, Qnil);
5354 startpos = PT; 5354 startpos = PT;
5355 startbyte = PT_BYTE; 5355 startbyte = PT_BYTE;
5356 } 5356 }
5357 5357
5358 SET_PT_BOTH (startpos, startbyte); 5358 SET_PT_BOTH (startpos, startbyte);
5359 lose = n < 0 && PT == BEGV; 5359 lose = n < 0 && PT == BEGV;
5360 Fvertical_motion (make_number (n), window); 5360 Fvertical_motion (make_number (n), window, Qnil);
5361 pos = PT; 5361 pos = PT;
5362 pos_byte = PT_BYTE; 5362 pos_byte = PT_BYTE;
5363 bolp = Fbolp (); 5363 bolp = Fbolp ();
@@ -5389,7 +5389,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5389 && (whole || !EQ (Vscroll_preserve_screen_position, Qt))) 5389 && (whole || !EQ (Vscroll_preserve_screen_position, Qt)))
5390 { 5390 {
5391 SET_PT_BOTH (pos, pos_byte); 5391 SET_PT_BOTH (pos, pos_byte);
5392 Fvertical_motion (original_pos, window); 5392 Fvertical_motion (original_pos, window, Qnil);
5393 } 5393 }
5394 /* If we scrolled forward, put point enough lines down 5394 /* If we scrolled forward, put point enough lines down
5395 that it is outside the scroll margin. */ 5395 that it is outside the scroll margin. */
@@ -5400,7 +5400,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5400 if (this_scroll_margin > 0) 5400 if (this_scroll_margin > 0)
5401 { 5401 {
5402 SET_PT_BOTH (pos, pos_byte); 5402 SET_PT_BOTH (pos, pos_byte);
5403 Fvertical_motion (make_number (this_scroll_margin), window); 5403 Fvertical_motion (make_number (this_scroll_margin), window, Qnil);
5404 top_margin = PT; 5404 top_margin = PT;
5405 } 5405 }
5406 else 5406 else
@@ -5412,7 +5412,7 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5412 else if (!NILP (Vscroll_preserve_screen_position)) 5412 else if (!NILP (Vscroll_preserve_screen_position))
5413 { 5413 {
5414 SET_PT_BOTH (pos, pos_byte); 5414 SET_PT_BOTH (pos, pos_byte);
5415 Fvertical_motion (original_pos, window); 5415 Fvertical_motion (original_pos, window, Qnil);
5416 } 5416 }
5417 else 5417 else
5418 SET_PT (top_margin); 5418 SET_PT (top_margin);
@@ -5424,7 +5424,8 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5424 /* If we scrolled backward, put point near the end of the window 5424 /* If we scrolled backward, put point near the end of the window
5425 but not within the scroll margin. */ 5425 but not within the scroll margin. */
5426 SET_PT_BOTH (pos, pos_byte); 5426 SET_PT_BOTH (pos, pos_byte);
5427 tem = Fvertical_motion (make_number (ht - this_scroll_margin), window); 5427 tem = Fvertical_motion (make_number (ht - this_scroll_margin), window,
5428 Qnil);
5428 if (XFASTINT (tem) == ht - this_scroll_margin) 5429 if (XFASTINT (tem) == ht - this_scroll_margin)
5429 bottom_margin = PT; 5430 bottom_margin = PT;
5430 else 5431 else
@@ -5438,10 +5439,10 @@ window_scroll_line_based (Lisp_Object window, int n, bool whole, int noerror)
5438 if (!NILP (Vscroll_preserve_screen_position)) 5439 if (!NILP (Vscroll_preserve_screen_position))
5439 { 5440 {
5440 SET_PT_BOTH (pos, pos_byte); 5441 SET_PT_BOTH (pos, pos_byte);
5441 Fvertical_motion (original_pos, window); 5442 Fvertical_motion (original_pos, window, Qnil);
5442 } 5443 }
5443 else 5444 else
5444 Fvertical_motion (make_number (-1), window); 5445 Fvertical_motion (make_number (-1), window, Qnil);
5445 } 5446 }
5446 } 5447 }
5447 } 5448 }
@@ -5999,7 +6000,7 @@ zero means top of window, negative means relative to bottom of window. */)
5999 if (start < BEGV || start > ZV) 6000 if (start < BEGV || start > ZV)
6000 { 6001 {
6001 int height = window_internal_height (w); 6002 int height = window_internal_height (w);
6002 Fvertical_motion (make_number (- (height / 2)), window); 6003 Fvertical_motion (make_number (- (height / 2)), window, Qnil);
6003 set_marker_both (w->start, w->contents, PT, PT_BYTE); 6004 set_marker_both (w->start, w->contents, PT, PT_BYTE);
6004 w->start_at_line_beg = !NILP (Fbolp ()); 6005 w->start_at_line_beg = !NILP (Fbolp ());
6005 w->force_start = 1; 6006 w->force_start = 1;
@@ -6040,7 +6041,7 @@ zero means top of window, negative means relative to bottom of window. */)
6040 if (w->vscroll) 6041 if (w->vscroll)
6041 XSETINT (arg, XINT (arg) + 1); 6042 XSETINT (arg, XINT (arg) + 1);
6042 6043
6043 return Fvertical_motion (arg, window); 6044 return Fvertical_motion (arg, window, Qnil);
6044} 6045}
6045 6046
6046 6047