diff options
| author | Chong Yidong | 2008-08-27 23:12:57 +0000 |
|---|---|---|
| committer | Chong Yidong | 2008-08-27 23:12:57 +0000 |
| commit | 48cdfb4b1778db5f05ae7894f6cd22ac09b04b18 (patch) | |
| tree | bf14707e8b0923bf9eb6f539c6d88bb70855e288 /src | |
| parent | 8fa97db1f30b75da4890936ffa5fe7e04def7ef7 (diff) | |
| download | emacs-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.c | 108 |
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)) |