aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChong Yidong2008-08-27 23:12:57 +0000
committerChong Yidong2008-08-27 23:12:57 +0000
commit48cdfb4b1778db5f05ae7894f6cd22ac09b04b18 (patch)
treebf14707e8b0923bf9eb6f539c6d88bb70855e288 /src
parent8fa97db1f30b75da4890936ffa5fe7e04def7ef7 (diff)
downloademacs-48cdfb4b1778db5f05ae7894f6cd22ac09b04b18.tar.gz
emacs-48cdfb4b1778db5f05ae7894f6cd22ac09b04b18.zip
(Fvertical_motion): Revert last change. Handle the general case where
we are moving forward, and PT spans multiple screen lines.
Diffstat (limited to 'src')
-rw-r--r--src/indent.c108
1 files changed, 61 insertions, 47 deletions
diff --git a/src/indent.c b/src/indent.c
index 62077d053e9..d08d4b3c7ca 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -2055,32 +2055,33 @@ whether or not it is currently displayed in some window. */)
2055 } 2055 }
2056 else 2056 else
2057 { 2057 {
2058 int it_start, oselective, first_x; 2058 int it_start, oselective, first_x, it_overshoot_expected;
2059 int start_string_newlines = 0;
2060 enum it_method omethod;
2061 2059
2062 SET_TEXT_POS (pt, PT, PT_BYTE); 2060 SET_TEXT_POS (pt, PT, PT_BYTE);
2063 start_display (&it, w, pt); 2061 start_display (&it, w, pt);
2064 first_x = it.first_visible_x; 2062 first_x = it.first_visible_x;
2065
2066 /* Scan from the start of the line containing PT. If we don't
2067 do this, we start moving with IT->current_x == 0, while PT is
2068 really at some x > 0. The effect is, in continuation lines, that
2069 we end up with the iterator placed at where it thinks X is 0,
2070 while the end position is really at some X > 0, the same X that
2071 PT had. */
2072 it_start = IT_CHARPOS (it); 2063 it_start = IT_CHARPOS (it);
2073 omethod = it.method;
2074 2064
2075 if (omethod == GET_FROM_STRING) 2065 /* See comments below for why we calculate this. */
2066 if (XINT (lines) > 0)
2076 { 2067 {
2077 char *s = SDATA (it.string) + IT_STRING_CHARPOS (it); 2068 if (it.method == GET_FROM_STRING)
2078 const char *e = s + SBYTES (it.string); 2069 {
2079 for (; s < e; s++) 2070 const char *s = SDATA (it.string);
2080 if (*s == '\n') 2071 const char *e = s + SBYTES (it.string);
2081 start_string_newlines++; 2072 while (s < e && *s != '\n')
2073 ++s;
2074 it_overshoot_expected = (s == e) ? -1 : 0;
2075 }
2076 else
2077 it_overshoot_expected = (it.method == GET_FROM_IMAGE
2078 || it.method == GET_FROM_STRETCH
2079 || it.method == GET_FROM_COMPOSITION);
2082 } 2080 }
2083 2081
2082 /* Scan from the start of the line containing PT. If we don't
2083 do this, we start moving with IT->current_x == 0, while PT is
2084 really at some x > 0. */
2084 reseat_at_previous_visible_line_start (&it); 2085 reseat_at_previous_visible_line_start (&it);
2085 it.current_x = it.hpos = 0; 2086 it.current_x = it.hpos = 0;
2086 /* Temporarily disable selective display so we don't move too far */ 2087 /* Temporarily disable selective display so we don't move too far */
@@ -2089,38 +2090,51 @@ whether or not it is currently displayed in some window. */)
2089 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); 2090 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
2090 it.selective = oselective; 2091 it.selective = oselective;
2091 2092
2092 if (XINT (lines) > 0) 2093 if (XINT (lines) <= 0)
2093 { 2094 {
2094 /* If we start on a multi-line string, move the iterator to 2095 it.vpos = 0;
2095 the last line of that string. */ 2096 /* Do this even if LINES is 0, so that we move back to the
2096 if (omethod == GET_FROM_STRING && start_string_newlines) 2097 beginning of the current line as we ought. */
2097 move_it_by_lines (&it, start_string_newlines, 0); 2098 if (XINT (lines) == 0 || IT_CHARPOS (it) > 0)
2098 2099 move_it_by_lines (&it, XINT (lines), 0);
2099 /* If we got too far, move back. This may happen if 2100 }
2100 truncate-lines is on and PT is beyond the right margin. 2101 else
2101 If the starting point is on an image, stretch glyph, 2102 {
2102 composition, or Lisp string, no need to backtrack... */ 2103 if (IT_CHARPOS (it) > PT)
2103 if (IT_CHARPOS (it) > it_start 2104 {
2104 && (omethod == GET_FROM_BUFFER 2105 /* IT may move too far if truncate-lines is on and PT
2105 || omethod == GET_FROM_DISPLAY_VECTOR 2106 lies beyond the right margin. In that case,
2106 || omethod == GET_FROM_C_STRING 2107 backtrack unless the starting point is on an image,
2107 /* ... except for one corner case: when the Lisp 2108 stretch glyph, composition, or Lisp string. */
2108 string contains a newline, or if there is a 2109 if (!it_overshoot_expected
2109 newline immediately afterwards (e.g. if there is 2110 /* Also, backtrack if the Lisp string contains no
2110 an overlay with an after-string just before the 2111 newline, but there is a newline right after it.
2111 newline). */ 2112 In this case, IT overshoots if there is an
2112 || (omethod == GET_FROM_STRING 2113 after-string just before the newline. */
2113 && (start_string_newlines 2114 || (it_overshoot_expected < 0
2114 || (it.method == GET_FROM_BUFFER 2115 && it.method == GET_FROM_BUFFER
2115 && it.c == '\n'))))) 2116 && it.c == '\n'))
2116 move_it_by_lines (&it, -1, 0); 2117 move_it_by_lines (&it, -1, 0);
2118 it.vpos = 0;
2119 move_it_by_lines (&it, XINT (lines), 0);
2120 }
2121 else
2122 {
2123 /* Otherwise, we are at the first row occupied by PT,
2124 which might span multiple screen lines (e.g., if it's
2125 on a multi-line display string). We want to start
2126 from the last line that it occupies. */
2127 it.vpos = 0;
2128 if (PT < ZV)
2129 {
2130 while (IT_CHARPOS (it) <= PT)
2131 move_it_by_lines (&it, 1, 0);
2132 move_it_by_lines (&it, XINT (lines) - 1, 0);
2133 }
2134 else
2135 move_it_by_lines (&it, XINT (lines), 0);
2136 }
2117 } 2137 }
2118
2119 it.vpos = 0;
2120 /* Do this even if LINES is 0, so that we move back
2121 to the beginning of the current line as we ought. */
2122 if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0)
2123 move_it_by_lines (&it, XINT (lines), 0);
2124 2138
2125 /* Move to the goal column, if one was specified. */ 2139 /* Move to the goal column, if one was specified. */
2126 if (!NILP (lcols)) 2140 if (!NILP (lcols))