Mercurial > emacs
comparison src/indent.c @ 97710:fd1ac489f6d6
(Fvertical_motion): If moving forward starting from a multi-line
string, move the iterator to the last line of that string.
author | Chong Yidong <cyd@stupidchicken.com> |
---|---|
date | Tue, 26 Aug 2008 00:04:02 +0000 |
parents | 029de4e224b6 |
children | 8ff0a4ca5511 |
comparison
equal
deleted
inserted
replaced
97709:a9d7c3ea6594 | 97710:fd1ac489f6d6 |
---|---|
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, it_overshoot_expected, first_x; | 2058 int it_start, oselective, first_x; |
2059 int start_string_newlines = 0; | |
2060 enum it_method omethod; | |
2059 | 2061 |
2060 SET_TEXT_POS (pt, PT, PT_BYTE); | 2062 SET_TEXT_POS (pt, PT, PT_BYTE); |
2061 start_display (&it, w, pt); | 2063 start_display (&it, w, pt); |
2062 first_x = it.first_visible_x; | 2064 first_x = it.first_visible_x; |
2063 | 2065 |
2066 really at some x > 0. The effect is, in continuation lines, that | 2068 really at some x > 0. The effect is, in continuation lines, that |
2067 we end up with the iterator placed at where it thinks X is 0, | 2069 we end up with the iterator placed at where it thinks X is 0, |
2068 while the end position is really at some X > 0, the same X that | 2070 while the end position is really at some X > 0, the same X that |
2069 PT had. */ | 2071 PT had. */ |
2070 it_start = IT_CHARPOS (it); | 2072 it_start = IT_CHARPOS (it); |
2071 | 2073 omethod = it.method; |
2072 /* We expect the call to move_it_to, further down, to overshoot | 2074 |
2073 if the starting point is on an image, stretch glyph, | 2075 if (omethod == GET_FROM_STRING) |
2074 composition, or Lisp string. We won't need to backtrack in | 2076 { |
2075 this situation, except for one corner case: when the Lisp | 2077 char *s = SDATA (it.string) + IT_STRING_CHARPOS (it); |
2076 string contains a newline. */ | |
2077 if (it.method == GET_FROM_STRING) | |
2078 { | |
2079 const char *s = SDATA (it.string); | |
2080 const char *e = s + SBYTES (it.string); | 2078 const char *e = s + SBYTES (it.string); |
2081 | 2079 for (; s < e; s++) |
2082 while (s < e && *s != '\n') | 2080 if (*s == '\n') |
2083 ++s; | 2081 start_string_newlines++; |
2084 | 2082 } |
2085 /* If there is no newline in the string, we need to check | |
2086 whether there is a newline immediately after the string | |
2087 in move_it_to below. This may happen if there is an | |
2088 overlay with an after-string just before the newline. */ | |
2089 it_overshoot_expected = (s == e) ? -1 : 0; | |
2090 } | |
2091 else | |
2092 it_overshoot_expected = (it.method == GET_FROM_IMAGE | |
2093 || it.method == GET_FROM_STRETCH | |
2094 || it.method == GET_FROM_COMPOSITION); | |
2095 | 2083 |
2096 reseat_at_previous_visible_line_start (&it); | 2084 reseat_at_previous_visible_line_start (&it); |
2097 it.current_x = it.hpos = 0; | 2085 it.current_x = it.hpos = 0; |
2098 /* Temporarily disable selective display so we don't move too far */ | 2086 /* Temporarily disable selective display so we don't move too far */ |
2099 oselective = it.selective; | 2087 oselective = it.selective; |
2100 it.selective = 0; | 2088 it.selective = 0; |
2101 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); | 2089 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS); |
2102 it.selective = oselective; | 2090 it.selective = oselective; |
2103 | 2091 |
2104 /* Move back if we got too far. This may happen if | 2092 if (XINT (lines) > 0) |
2105 truncate-lines is on and PT is beyond right margin. | 2093 { |
2106 Don't go back if the overshoot is expected (see above). */ | 2094 /* If we start on a multi-line string, move the iterator to |
2107 if (IT_CHARPOS (it) > it_start && XINT (lines) > 0 | 2095 the last line of that string. */ |
2108 && (!it_overshoot_expected | 2096 if (omethod == GET_FROM_STRING && start_string_newlines) |
2109 || (it_overshoot_expected < 0 | 2097 move_it_by_lines (&it, start_string_newlines, 0); |
2110 && it.method == GET_FROM_BUFFER | 2098 |
2111 && it.c == '\n'))) | 2099 /* If we got too far, move back. This may happen if |
2112 move_it_by_lines (&it, -1, 0); | 2100 truncate-lines is on and PT is beyond the right margin. |
2101 If the starting point is on an image, stretch glyph, | |
2102 composition, or Lisp string, no need to backtrack... */ | |
2103 if (IT_CHARPOS (it) > it_start | |
2104 && (omethod == GET_FROM_BUFFER | |
2105 || omethod == GET_FROM_DISPLAY_VECTOR | |
2106 || omethod == GET_FROM_C_STRING | |
2107 /* ... except for one corner case: when the Lisp | |
2108 string contains a newline, or if there is a | |
2109 newline immediately afterwards (e.g. if there is | |
2110 an overlay with an after-string just before the | |
2111 newline). */ | |
2112 || (omethod == GET_FROM_STRING | |
2113 && (start_string_newlines | |
2114 || (it.method == GET_FROM_BUFFER | |
2115 && it.c == '\n'))))) | |
2116 move_it_by_lines (&it, -1, 0); | |
2117 } | |
2113 | 2118 |
2114 it.vpos = 0; | 2119 it.vpos = 0; |
2115 /* Do this even if LINES is 0, so that we move back | 2120 /* Do this even if LINES is 0, so that we move back |
2116 to the beginning of the current line as we ought. */ | 2121 to the beginning of the current line as we ought. */ |
2117 if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0) | 2122 if (XINT (lines) >= 0 || IT_CHARPOS (it) > 0) |