diff options
| author | Chong Yidong | 2008-08-26 00:04:02 +0000 |
|---|---|---|
| committer | Chong Yidong | 2008-08-26 00:04:02 +0000 |
| commit | 72ad106bfa72016d5e7889f46b3a231ff92a23ea (patch) | |
| tree | c2ad15fa7e58488d798ecea5b17dad1c1e059b45 /src/indent.c | |
| parent | ff73b4611e91d5afbc627e41c6224bafd9a06b73 (diff) | |
| download | emacs-72ad106bfa72016d5e7889f46b3a231ff92a23ea.tar.gz emacs-72ad106bfa72016d5e7889f46b3a231ff92a23ea.zip | |
(Fvertical_motion): If moving forward starting from a multi-line
string, move the iterator to the last line of that string.
Diffstat (limited to 'src/indent.c')
| -rw-r--r-- | src/indent.c | 65 |
1 files changed, 35 insertions, 30 deletions
diff --git a/src/indent.c b/src/indent.c index d556cd87748..62077d053e9 100644 --- a/src/indent.c +++ b/src/indent.c | |||
| @@ -2055,7 +2055,9 @@ whether or not it is currently displayed in some window. */) | |||
| 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); |
| @@ -2068,30 +2070,16 @@ whether or not it is currently displayed in some window. */) | |||
| 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); |
| 2073 | omethod = it.method; | ||
| 2071 | 2074 | ||
| 2072 | /* We expect the call to move_it_to, further down, to overshoot | 2075 | if (omethod == GET_FROM_STRING) |
| 2073 | if the starting point is on an image, stretch glyph, | ||
| 2074 | composition, or Lisp string. We won't need to backtrack in | ||
| 2075 | this situation, except for one corner case: when the Lisp | ||
| 2076 | string contains a newline. */ | ||
| 2077 | if (it.method == GET_FROM_STRING) | ||
| 2078 | { | 2076 | { |
| 2079 | const char *s = SDATA (it.string); | 2077 | char *s = SDATA (it.string) + IT_STRING_CHARPOS (it); |
| 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 | |||
| 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 | } | 2082 | } |
| 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; |
| @@ -2101,15 +2089,32 @@ whether or not it is currently displayed in some window. */) | |||
| 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 |