diff options
| author | Eli Zaretskii | 2015-02-09 18:24:46 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2015-02-09 18:24:46 +0200 |
| commit | 403cb178c75a80603dbd8ed23e342d2109645401 (patch) | |
| tree | 815315bef8212ed239805f13089612ebcef78a82 | |
| parent | af560cd6f15e7cc7e42bff5b3c802b9d1d1640b5 (diff) | |
| download | emacs-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/ChangeLog | 5 | ||||
| -rw-r--r-- | doc/lispref/positions.texi | 10 | ||||
| -rw-r--r-- | src/ChangeLog | 7 | ||||
| -rw-r--r-- | src/indent.c | 55 | ||||
| -rw-r--r-- | src/window.c | 21 |
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 @@ | |||
| 1 | 2015-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 | |||
| 1 | 2015-02-06 Nicolas Petton <nicolas@petton.fr> | 6 | 2015-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 | |||
| 493 | improve the performance of your code. @xref{Truncation, cache-long-scans}. | 493 | improve 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 |
| 497 | This function moves point to the start of the screen line @var{count} | 497 | This function moves point to the start of the screen line @var{count} |
| 498 | screen lines down from the screen line containing point. If @var{count} | 498 | screen lines down from the screen line containing point. If @var{count} |
| 499 | is negative, it moves up instead. | 499 | is negative, it moves up instead. |
| @@ -515,6 +515,14 @@ The window @var{window} is used for obtaining parameters such as the | |||
| 515 | width, the horizontal scrolling, and the display table. But | 515 | width, 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 | |||
| 519 | The optional argument @var{cur-col} specifies the current column when | ||
| 520 | the function is called. This is the window-relative horizontal | ||
| 521 | coordinate of point, measured in units of font width of the frame's | ||
| 522 | default face. Providing it speeds up the function, especially in very | ||
| 523 | long lines, because it doesn't have to go back in the buffer in order | ||
| 524 | to determine the current column. Note that @var{cur-col} is also | ||
| 525 | counted 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 @@ | |||
| 1 | 2015-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 | |||
| 1 | 2015-02-09 Dima Kogan <dima@secretsauce.net> | 8 | 2015-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 | ||
| 1931 | DEFUN ("vertical-motion", Fvertical_motion, Svertical_motion, 1, 2, 0, | 1931 | DEFUN ("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. |
| 1933 | If LINES is negative, this means moving up. | 1933 | If LINES is negative, this means moving up. |
| 1934 | 1934 | ||
| @@ -1951,12 +1951,18 @@ is). If the line is scrolled horizontally, COLS is interpreted | |||
| 1951 | visually, i.e., as addition to the columns of text beyond the left | 1951 | visually, i.e., as addition to the columns of text beyond the left |
| 1952 | edge of the window. | 1952 | edge of the window. |
| 1953 | 1953 | ||
| 1954 | The optional third argument CUR-COL specifies the horizontal | ||
| 1955 | window-relative coordinate of point, in units of frame's canonical | ||
| 1956 | character width, where the function is invoked. If this argument is | ||
| 1957 | omitted or nil, the function will determine the point coordinate by | ||
| 1958 | going back to the beginning of the line. | ||
| 1959 | |||
| 1954 | `vertical-motion' always uses the current buffer, | 1960 | `vertical-motion' always uses the current buffer, |
| 1955 | regardless of which buffer is displayed in WINDOW. | 1961 | regardless of which buffer is displayed in WINDOW. |
| 1956 | This is consistent with other cursor motion functions | 1962 | This is consistent with other cursor motion functions |
| 1957 | and makes it possible to use `vertical-motion' in any buffer, | 1963 | and makes it possible to use `vertical-motion' in any buffer, |
| 1958 | whether or not it is currently displayed in some window. */) | 1964 | whether 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 | ||