Mercurial > emacs
comparison src/indent.c @ 97781:8ff0a4ca5511
(Fvertical_motion): Revert last change. Handle the general case where
we are moving forward, and PT spans multiple screen lines.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Wed, 27 Aug 2008 23:12:57 +0000 |
parents | fd1ac489f6d6 |
children | 36198ccea250 |
comparison
equal
deleted
inserted
replaced
97780:0ad50f1c1e6b | 97781:8ff0a4ca5511 |
---|---|
2053 pos = *vmotion (PT, XINT (lines), w); | 2053 pos = *vmotion (PT, XINT (lines), w); |
2054 SET_PT_BOTH (pos.bufpos, pos.bytepos); | 2054 SET_PT_BOTH (pos.bufpos, pos.bytepos); |
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; |
2063 it_start = IT_CHARPOS (it); | |
2064 | |
2065 /* See comments below for why we calculate this. */ | |
2066 if (XINT (lines) > 0) | |
2067 { | |
2068 if (it.method == GET_FROM_STRING) | |
2069 { | |
2070 const char *s = SDATA (it.string); | |
2071 const char *e = s + SBYTES (it.string); | |
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); | |
2080 } | |
2065 | 2081 |
2066 /* Scan from the start of the line containing PT. If we don't | 2082 /* 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 | 2083 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 | 2084 really at some x > 0. */ |
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); | |
2073 omethod = it.method; | |
2074 | |
2075 if (omethod == GET_FROM_STRING) | |
2076 { | |
2077 char *s = SDATA (it.string) + IT_STRING_CHARPOS (it); | |
2078 const char *e = s + SBYTES (it.string); | |
2079 for (; s < e; s++) | |
2080 if (*s == '\n') | |
2081 start_string_newlines++; | |
2082 } | |
2083 | |
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 */ |
2087 oselective = it.selective; | 2088 oselective = it.selective; |
2088 it.selective = 0; | 2089 it.selective = 0; |
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); |
2117 } | 2118 it.vpos = 0; |
2118 | 2119 move_it_by_lines (&it, XINT (lines), 0); |
2119 it.vpos = 0; | 2120 } |
2120 /* Do this even if LINES is 0, so that we move back | 2121 else |
2121 to the beginning of the current line as we ought. */ | 2122 { |
2122 if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0) | 2123 /* Otherwise, we are at the first row occupied by PT, |
2123 move_it_by_lines (&it, XINT (lines), 0); | 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 } | |
2137 } | |
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)) |
2127 { | 2141 { |
2128 /* If the window was originally hscrolled, move forward by | 2142 /* If the window was originally hscrolled, move forward by |